背景

我们知道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. 第一天 Linux 是什么

    众所周知,Linux的核心原型是1991年由托瓦兹(Linus Torvalds)写出来 计算机是由一堆硬件所组成的,为了有敁率的控制这些硬件资源,于是乎就有操作系统产生了.       到了1985 ...

  2. 通过/etc/rc.local实现开机自动拉起服务

    添加服务到/etc/rc.local 如自动拉起apache服务: /etc/rc.local: #!/bin/sh # # This script will be executed *after* ...

  3. ajax教程完整版

    第 1 页 Ajax 简介 Ajax 由 HTML.JavaScript™ 技术.DHTML 和 DOM 组成,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序.本文的作者是 ...

  4. 好的 iOS 代码习惯

    一,使用别人的框架时,尽量在退出时移除框架创建的对象 if (_giftToastView) { [_giftToastView removeFromSuperview]; _giftToastVie ...

  5. iOS上让按钮文本左对齐问题

    一,问题分析 1.在做历史记录视图的时候,由于让键盘退出后才能触发表格的 didselect 那个代理方法,也就是得点两下才触发,而表格中的按钮点一下就可以立即响应. 2.于是我就有了用按钮事件代替 ...

  6. Selenium_获取相对坐标

    <html> <head> <title>位置</title> <style> .test { background: url(" ...

  7. 20145330第九周《Java学习笔记》

    20145330第九周<Java学习笔记> 第十六章 整合数据库 JDBC入门 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JD ...

  8. 【原创】windows下搭建vue开发环境+IIS部署

    [原创]win10下搭建vue开发环境  如果要转发,请注明原作者和原产地,谢谢! 特别说明:下面任何命令都是在windows的命令行工具下进行输入,打开命令行工具的快捷方式如下图:     详细的安 ...

  9. border-radius 圆角半径

    CSS3属性之一:border-radius 语法: border-radius : none | <length>{1,4} [ / <length>{1,4} ]? 相关属 ...

  10. [LintCode] Two Sum 两数之和

    Given an array of integers, find two numbers such that they add up to a specific target number. The ...