背景

我们知道Unity3d是通过C#脚本语言的形式来实现游戏的逻辑代码编写,同样SCOTT服务器也设置了通过C#脚本来实现游戏逻辑,但是本文并不是想真正分析解密他们的运行机制,只是想通过自己的一个需求,来探讨总结下其中的原理。

下面来说下我自己的需求,比较简单,由于经常在非开发环境部署一些小工具,做系统维护,但每次又懒得带笔记本和编译环境到现场,但系统数据又总是那么奇葩,时常有bug出现,突发奇想是否是能把工具做成脚本,这样现场就很容易进行调整(简单修改脚本),现场搞定不用来回折腾,岂不是很Happy。

声明:本文首发于蛮牛,次发博客园,本人原创。

http://www.manew.com/thread-96136-1-1.html

原理

Unity3d使用的Mono这个地球人知道,Scott呢?我以前分析过其源码,大概知道它需要兼容IconPyhton和C#两种脚本,所以它做了一层封装,但是看它引用的DLL lib有Mono的影子,所以估计也是Mono(不对请拍砖,其实它用什么无所谓了)。实际原理很简单了,也就是脚本动态编译(有点像解释执行,严格上应该不是,我觉得李总的热更新的脚本应该不是动态编译的因为很多平台根本不支持比如IOS),查了下资料目前c#动态编译的一共三种方式CodeDom,Mono,Roslyn,这三种教程应该是一堆一堆的,但是Mono和Roslyn的都不是很多,毕竟这个需求比较小众,而且Roslyn是最新出来的,例子都是“Hello world”级别的让人很不爽,最后发现一个库CS-Script,网址是https://csscriptsource.codeplex.com/,看了下文档,瞟一眼代码:

CSScript.EvaluatorConfig.Engine = EvaluatorEngine.Roslyn;
//EvaluatorEngine.Mono;
//EvaluatorEngine.CodeDom; var sqr = CSScript.Evaluator
.CreateDelegate(@"int Sqr(int a)
{
return a * a;
}"); var r = sqr(3);
看到1,2,3行代码的时候,我会心的笑了,实际上CS-Script是对于三种方式的上层封装,可以自定义选择用那一种,这个方案对于我的已经够用了。下面就是做个试验,然后实施即可。

试验

详细的步骤教,我不想多说了CS-Script有自己详细的教程。由于本人的需求是使用自己写的代码调用脚本,这里就不讲通过命令执行脚本的东东了。
第一步安装,创建一个控制台项目,然后使用nuget进行CS-Script的安装,在程序管理控制台执行
Install-Package CS-Script 

Nuget会自动下载相关的DLL和Example脚本到项目中很简单,结果如下

其中下面上个脚本是自动添加的例子程序,打开看看很简单,这里就不表了

在Main函数中添加如下代码,测试(这里编译竟然发现有错误,可能是缺Roslyn引用,无卵用,直接剔除或者注释)

static void Main(string[] args)
{
    HostApp.Test();
}

执行效果如下,具体可以看Test中的方法就是一些如何动态执行类,方法,静态方法,接口等等简单例子吧,对于我们的简单需求已经够用了(如果有复杂需求比如Host,上下文,高级动态编译什么的请看文档,这里估计也讲不下)

至此简单的测试环境已经有了

实施

根据官方的例子稍微做一下改造,修改Main函数如下:

在bin下写一个自己的Hello.cs脚本:

创建一个批处理执行,以便把文件名称作为动态参数传入,执行效果如下

这里需要注意的是脚本的文件格式别忘记是utf-8的格式,不然中文会乱码的。

应用

上文中的脚本运行模板写基本完成了,这样只要将自己需执行的工具代码,放到单独的类中,然后启动函数为Run即可,这样只要在Dos批处理脚本中修改c#代码文件的相应名称就可以按照脚本执行了,下面是我的工具脚本代码(是一个压缩二级目录的C#源码):

满心欢喜,可结果可耻的失败了

分析其原因主要是我在Myscript脚本中使用了另一个c#类文件中的相关函数,也就是上图中的红色框标注出的代码,实际上这里是一个上下文缺失(或者是host问题),这里的解决办法一种是动态添加Assembly;一种是使用DLL。这里为了简单,我选择第二种方法。这里假设ZipUtil是一种公用类库,我将其封装到独立的DLL中,作为类库引用到工程中去。运行结果和预想的一样执行成功了(So happy)

这里也体现了CS-Script的强大,动态的就管理了第三方应用的DLL竟然不需要做任何处理,赞一个!

总结

至此,小试牛刀使用CS-Script这个工具,很Easy就实现了C#脚本的动态调用和执行,也抛砖引玉引入了C#作为脚本动态编译执行的原理和过程,当然复杂的应用还有很多,比如执行效率,热插拔更新,高级动态编译,上下文这里留给大家自己研究吧。

对本人来说作为自己的需求已经达到,对于动态执行C#脚本也有了更深刻的认识,特别是通过排错的过程,更加深刻的认识到使用脚本的前提和环境是什么:脚本最好是一个单独的C#文件即可(多了就失去了脚本的意义,也没有必要);脚本的使用是在有完善的类库的前提下,通过脚本来实现多变的逻辑,如果类库不够成熟稳定还是不要使用脚本了(这里可以参考下Scott至少它提供了Framework级别的库)

源码下载

参考阅读:

C#脚本引擎 CS-Script 之(一)——初识 http://www.cnblogs.com/strinkbug/p/4697034.html

小试牛刀C#作为脚本语言执行解密的更多相关文章

  1. js脚本语言在页面上不执行

    转换原理:// 编码原理就是创建TextNode节点,附加到容器中,再取容器的innerHTML.(将脚本编码) // 解码原理是将字符串赋給容器的innerHTML,再取innerText或text ...

  2. java 计算数学表达式及执行脚本语言

    java SE6中对常用的脚本语言做了支持. 可供使用者在java代码中执行脚本语言,还可以利用get("key"),put("key","value ...

  3. L脚本语言实现文件加解密

    L脚本语言中能够对内存对象进行AES加解密.我们能够非常easy地实现文件加解密 #scp #定义一个秘钥字符串 定义:字符串,str1,abcdefg 打开:文件,file1,c:\1.txt 打开 ...

  4. L脚本语言语法手冊 0.10版

    L脚本语言语法手冊 0.10版       简  介 L脚本语言是一个轻量级的,旨在接近自然语言的编程语言,眼下支持在中文.英文基础上的编程.并可扩展为随意语种.L脚本语言的语法结构简单.程序结构相对 ...

  5. InstallShield 脚本语言学习笔记

    InstallShield脚本语言是类似C语言,利用InstallShield的向导或模板都可以生成基本的脚本程序框架,可以在此基础上按自己的意愿进行修改和添加.     一.基本语法规则      ...

  6. Unity中脚本的执行顺序总结(@WhiteTaken)

    (Editor)以上是Unity官方文档中的截图,脚本在被挂载到物体上,会启用Editor的方法Reset. (Initialization)当执行脚本开始,初始化的过程中,依次执行的是Awake-& ...

  7. 使用Lua脚本语言开发出高扩展性的系统,AgileEAS.NET SOA中间件Lua脚本引擎介绍

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  8. .NET 动态脚本语言Script.NET 入门指南 Quick Start

    Script.NET是一种动态的脚本语言,它使得程序可扩展,可定制,和维护性好.和Office系列的VB Script相似,可以在应用中嵌入大量的代码块,以便在运行时才执行这些代码. Script.N ...

  9. [Java面试九]脚本语言知识总结.

    核心内容概述 1.JavaScript加强,涉及到ECMAScript语法.BOM对象.DOM对象以及事件. 2.Ajax传统编程. 3.jQuery框架,九种选择器为核心学习内容 4.JQuery ...

随机推荐

  1. 【BZOJ】3211: 花神游历各国

    题意 \(n\)个点,第\(i\)个点值为\(a_i\).\(m\)个询问,每次询问\([l, r]\)内的和或者将\([l, r]\)的每个值改为自己的算术平方根.(\(n \le 100000, ...

  2. tornado 学习笔记1 引言

    从事软件开发这行业也快5年啦,其实从事的工作也不完全是软件开发,软件开发只是我工作中的一部分.其中包括课题研究.信息化方案设计.软件开发.信息系统监理.项目管理等工作,比较杂乱.开发的软件比较多,但是 ...

  3. tomcat、腾讯云主机和微信

    腾讯云主机和微信 申请一个腾讯云上的服务器(在这里我是申请的Linux系统,里面自己事先装好了tomcat.jdk等所需要用到的工具,注意做好必要的配置工作) 连接服务器和部署项目时必要的步骤:1.将 ...

  4. 无法将Win7安装到GPT分区下解决办法

    当出现"您想将windows安装 在何处时",按shift+F10打开命令提示符,输入:diskpartlist disksel disk 0cleanconvert mbr完成转 ...

  5. Compound Words

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=91209#problem/C 题意:   有一堆按照字典序排好的字符串,问你有多 ...

  6. 李洪强经典面试题136-KVO-KVC

    李洪强经典面试题136-KVO-KVC   KVC-KVO KVC的底层实现? 当一个对象调用setValue方法时,方法内部会做以下操作: ①检查是否存在相应key的set方法,如果存在,就调用se ...

  7. 李洪强iOS经典面试题124

    1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承;可以实现多个接口,通过实现 ...

  8. [LintCode] Coins in a Line II 一条线上的硬币之二

    There are n coins with different value in a line. Two players take turns to take one or two coins fr ...

  9. 关于JS的算法

    一.快速排序 function qSort(arr) { if(arr.length === 0) { return []; } var left = []; var right = []; var ...

  10. oracle中删除表中某字段出现重复的信息 保留其中一条

    记得以前有个同事问过我这个,说是以前面试的时候碰到的问题,下面我介绍三种方法. 首先我们在这里创建一个测试表添加相应的测试数据. create table test  (id number,name ...