`
pavel
  • 浏览: 930605 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

.NET 脚本

阅读更多

简介
你知道我对于前.NET时代有什么留恋吗?脚本!我喜欢创建一个小巧的脚本文件为我完成一些小任务,或者为了测试一小段代码而无需创建一项工程或是解决方案。我喜欢处理和清除的仅仅是一个小巧的文件而不是一个解决方案文件夹,工程文件夹和附带的bin 和obj 文件夹。我怀念那些时光,这正是我创建 .NET 脚本的原因。

什么是.NET 脚本呢?

基本上,它就是一个简单的控制台应用程序,从 .dnml 文件( Dot Net Markup Language, .NET 标记语言, 这是我定义的,哈哈)中读取 XML 文档。这个XML文档包含如下子元素,存储程序集引用,编写的代码所属的语言以及实际的要编译和执行的代码。那个控制台应用程序,我称之为脚本引擎,读取XML 文本并分析出需要的数据。然后它利用CSharp, VisualBasic, 和 CodeDom 命名空间中的类编译代码并将作为结果的程序集装载到内存中。教本引擎利用反射机制执行生成的程序集中的入口函数。当用户关闭控制台窗口时,脚本引擎被关闭,在内存中的程序集将不复存在,它将被垃圾回收器清理掉。没有任何的库或可执行程序生成。

Dot Net 标记语言
让我们来看看.NET 标记语言是什么模样的。它其实非常简单。下面就是一个它的例子。我会一一说明XML 文档中的每个元素。

<dnml>
<reference assembly="System.Windows.Forms.dll" />
<language name="C#" />
<scriptCode><![CDATA[
using System.Windows.Forms;
public class Test
{
   public static void Main()
   {
       Console.WriteLine("This is a test");
       MessageBox.Show("This is another test");
       Test2 two = new Test2();
       two.Stuff();
   }
}
public class Test2
{
 public void Stuff()
 {
  Console.WriteLine("Instance call");
 }
}
]]></scriptCode>
</dnml>
该文档XML元素称为 <dnml> (你能猜出它代表什么吗?)。在这个元素内部有三个不同的子元素,你能用它们来定义脚本如何编译。

首先是 <reference> 元素,它只有一个属性,叫“Assembly”。“Assembly”属性包含你要引用的程序集名称(包含文件扩展名)。一个.dnml 文档可以包含许多<reference> 元素,它对应于你在VS.NET 中向工程中添加的引用列表。 对于每一个你的代码执行所需要的引用,都必须添加一个<reference assembly="" /> 元素。

基于程序集探测的考虑,任何你所引用的GAC 程序集都会被CLR自动找到。但是如果你引用了一个不是GAC中的程序集,情况就不同了。假设你引用了一个称为Common.dll 的非GAC 程序集。为了让您的.NET 脚本正确执行,Common.dll 必须放在两个地方。首先它必须放在你的.dnml 文件所属的文件夹中。其次,它必须放在脚本引擎所在的文件夹中。我正在试图解决这个问题,但是就目前来说非GAC 程序集必须存放在两个不同的文件夹中。

下一个元素是<language> ,它有一个属性,称为 'name'。一个.dnml 文件只能有一个语言元素。对于’name’ 属性两个可能的值是 'C#' 和 'VB', 我希望他们是自描述的。

最后一个元素是<scriptCode> , 它含有一个CDATA XML 元素。这个元素里包含了当你执行该.dnml 文件时将要执行的代码。但是为了使用它你必须遵循一些接口规则。首先,它实际上只是普通的内嵌C# 和 VB.NET, 所有的方法和字段都必须放在类里面。其次,你可以定义任意多个类,但是必须有一个类拥有一个公有静态函数,称为 “Main”, 没有任何输入参数,也不返回结果。只是脚本引擎通过反射搜索到的入口方法;如果找到,将会调用它。当然,“Main”方法放在哪个类中是无关紧要的,因为脚本引擎将会遍历定义的每个类型,直到它找到Main 方法为止。

脚本引擎是怎样工作的?
脚本引擎的大多数代码都是很直观的,因此我会一一描述它的每个方面。当中有一个非常有趣的部分就是一个名为AssemblyGenerator 的类,它只有一个方法,称为CreateAssembly()。这个方法将完成所有的工作,编译并生成一个新的程序集,正如下面所看到的.

//Create an instance of the C# compiler  
CodeDomProvider codeProvider = null;
if (code.IsCSharp)
   codeProvider = new CSharpCodeProvider();
else
   codeProvider = new VBCodeProvider();
ICodeCompiler compiler = codeProvider.CreateCompiler();
首先我需要声明一个类CodeDomProvider 的实例。它是类 CSharpCodeProvider 和类VBCodeProvider 的基类。你可以使用这些语言的特定 XxxProvider 对象来创建一个 CodeGenerator 对象,它将被用来根据它包含的你创建的CodeDom 对象图生成代码。你可以创建一个CodeParser 对象,它将根据你传入的源代码字符串生成一个CodeDom 对象图(在当前1.1 .NET Framework 版本中, 它将返回空值) 。XxxProvider 对象也可以用来创建一个CodeCompiler , 这正是我这里所使用的。 CodeCompiler 类就是我用来编译.dnml 文件中的代码,并生成新的程序集的类。

所以,基于.dnml 文件中所定义的语言类型,我创建一个合适的XxxCodeProvider 对象。从这个对象,我请求一个CodeCompiler 实例,它将是基于语言不同而不同的。

//add compiler parameters
CompilerParameters compilerParams = new CompilerParameters();
compilerParams.CompilerOptions = "/target:library /optimize";
compilerParams.GenerateExecutable = false;
compilerParams.GenerateInMemory = true;
compilerParams.IncludeDebugInformation = false;
compilerParams.ReferencedAssemblies.Add("mscorlib.dll");
compilerParams.ReferencedAssemblies.Add("System.dll");
  
//add any aditional references needed
foreach (string refAssembly in code.References)
   compilerParams.ReferencedAssemblies.Add(refAssembly);
下一步,我创建一个CompilerParameters 对象。这个类基本上包装了当你手工通过csc.exe (C# 编译器) 和 vbc.exe (VB.NET 编译器) 编译一个程序集时所用的所有命令行参数。一个特别重要的参数就是属性GenerateInMemory,  这里我用到了它。它能确保当代码编译时,生成的程序集只会驻存在内存中,而不会作为结果创建任何文件。

该代码的最后一部分将脚本代码所需要的所有引用添加到CompilerParameters中。 默认情况下,我添加了对于mscorlib.dll 和 system.dll 的引用。然后我添加了对于.dnml 文件中每一个<reference> 元素所标明的程序集的引用。

//actually compile the code
CompilerResults results = compiler.CompileAssemblyFromSource(
                             compilerParams,  code.SourceCode));
//Do we have any compiler errors
if (results.Errors.Count > 0)
{
   foreach (CompilerError error in results.Errors)
      DotNetScriptEngine.LogAllErrMsgs("Compine Error:"+error.ErrorText);
   return null;
}
然后,我调用了CodeCompiler.CompileAssemblyFromSource, 它传入CompilerParameters 对象和包含所要编译的实际代码的字符串变量。返回的对象属于类CompilerResults. 当编译出现错误时,这个对象包含一个CompileError 对象的集合,我将用它显示给用户当编译时那些地方出错了。

//get a hold of the actual assembly that was generated
Assembly generatedAssembly = results.CompiledAssembly;
//return the assembly
return generatedAssembly;
}
如果脚本代码编译成功,CompilerReslts 对象将包含一个对于新编译和创建的程序集的引用。我保留该对象并返回给调用方法。

一旦程序集成功创建并返回,脚本引擎将利用反射遍历每一个生成的类型,寻找一个叫'Main' 的静态方法。如果找到了,就再次利用反射执行它。如果没有找到,它将返回给用户一个错误,用来解释发生的问题。

最后一步
.NET 脚本引擎还能够添加和删除.dnml 文件的关联。这意味着一旦文件关联好,你为了执行.dnml 文件只需双击它就可以了。 当你做个时,脚本引擎将会执行,一个相关路径的命令行参数和该 .dnml 文件名将传递给它。接着教本引擎将读取该文件并处理相应的XML。

为了创建.dnml 文件和.NET 脚本引擎之间的关联,你只需双击DotNetScriptEngine.exe 就可以了。当它不带任何命令行参数执行时,它将在您的服务器上创建文件关联。如果你在控制台运行DotNetScriptEngine.exe, 并传入'remove' 参数,该引擎将会在您的服务器上删除文件关联。

翻译的 http://www.codeproject.com/KB/dotnet/DotNetScript.aspx

分享到:
评论

相关推荐

    asp.net脚本博客系统

    【ASP.NET脚本博客系统详解】 ASP.NET是微软公司推出的一种用于构建Web应用程序的框架,它基于.NET Framework,提供了一种高效、安全且易于维护的平台来开发动态网站。在这个"asp.net脚本博客系统"中,我们主要探讨...

    Script.NET脚本语言开发平台

    Script.NET是通用的脚本语言开发平台,目前支持Tcl、Python、Lua、NSIS脚本的开发,支持脚本语言的开发、运行、调试、编译、生成可执行文件等功能。Script.NET采用类似于Eclipse的插件化开发方式,大部分功能都以...

    VB.NET genesis2000脚本接口及演示

    在本示例中,“VB.NET genesis2000脚本接口及演示”是为了帮助开发者使用VB.NET与Genesis2000进行交互,实现自动化脚本的编写。 首先,让我们深入理解 Genesis2000 脚本接口。脚本接口允许程序员通过编程方式调用...

    Script.NET脚本语言开发平台2.1.1版本

    Script.NET是蓝蚂蚁工作室开发的一套用于Tcl/Python/Ruby/Lua/NSIS 等脚本语言开发的集成开发环境,刚刚发布的2.1.1版本新增了Ruby脚本的支持,可以支持Ruby脚本的开发、调试、生成可执行文件、控制台等功能,可以...

    一个用于制作C# 或者VB.NET编辑器

    SharpDevelop 是一个用于制作 C# 或者 VB.NET 的项目而设计的一个编 辑器,同时,这个编辑器本身就是使用 C# 开发的,而且公开了全部源代 码,因此这个工具本身也是学习 C# 以及软件开发规范的一个很好材料。...

    基于 .Net 框架的用来替代 vbs 的 Windows 脚本工具集分享给需要的同学

    基于 .Net 框架的用来替代 vbs 的 Windows 脚本工具集; 脚本宿主和相关文件 wnscript.exe - .Net Windows 脚本宿主; cnscript.exe - .Net Console 脚本宿主; checkpath.exe - 命令行工具,检查命令的文件路径; 脚本...

    paxScript.NET v2.8 for .net2.0版本dll

    paxScript.NET 脚本引擎包括 C# 和 VB.NET 语言的解释器。 paxScript.NET 的主要特点是: paxScript.NET 是用 C# 编写的。paxScript.NET 源代码符合CLS标准。 paxScript.NET 将程序编译为字节码。它不使用 CodeDOM...

    paxScript.NET v2.8 for .net4.0版本dll

    paxScript.NET 脚本引擎包括 C# 和 VB.NET 语言的解释器。 paxScript.NET 的主要特点是: paxScript.NET 是用 C# 编写的。paxScript.NET 源代码符合CLS标准。 paxScript.NET 将程序编译为字节码。它不使用 CodeDOM...

    NetScript:适用于本机应用程序的仅Windows .NET脚本的概念证明

    标题中的“NetScript”指的是一个特定的项目或技术,它是一个专为本地应用程序设计的、仅限于Windows操作系统的.NET脚本解决方案。这个概念证明可能是为了展示如何在不使用传统编译语言(如C#)的情况下,利用.NET...

    jssc:Microsoft JScript.net 脚本编译器

    jssc jssc 代表 JScript.net 脚本编译器。...调用编译器目录下的jssc.cmd或者jssc shell脚本,即这个README所在的目录,这样就把jssc.jss模块编译到%TEMP%目录下,可以安全删除Microsoft JScript.net脚本编译器

    ASP.NET IIS 注册工具

    - `-lk`:列出所有包含ASP.NET脚本映射的IIS元数据库路径和版本。 - `-lv`:显示所有安装的ASP.NET版本的状态和安装路径。 - `-r`:更新所有脚本映射,使其指向与工具关联的ASP.NET ISAPI版本。 - `-s`:将脚本映射...

    FastReport.NET中文用户手册

    4. **脚本支持**:FastReport.NET支持内置的Visual Basic .NET脚本引擎,开发者可以通过脚本控制报表的各个细节,实现更复杂的功能。 5. **预览和导出**:报表可以实时预览,且支持多种格式的导出,如PDF、HTML、...

    FastReport.Net v1.2.47

    3. **强大的脚本支持**:FastReport.Net支持内置的Visual Basic .NET脚本引擎,允许用户在报表中编写脚本,实现复杂的逻辑处理,如计算、过滤、排序等。 4. **多语言支持**:FastReport.Net支持多语言报表,开发者...

    【ASP.NET编程知识】在IIS上重新注册.NET Framework 2.0的命令和参数详解.docx

    12. `-lk`:列出包含ASP.NET脚本映射的所有IIS元数据库项的路径及其版本。 13. `-c`:安装客户端脚本的此版本到每个IIS站点目录的aspnet_client子目录中。 14. `-e`:从每个IIS站点目录的aspnet_client子目录中...

    FastReport.Net v2017.1.16(绿色、无水印)

    4. **强大的脚本支持**:使用内置的Visual Basic .NET脚本引擎,用户可以在报表中编写脚本,实现动态计算、条件判断和自定义逻辑,增强了报表的灵活性和功能性。 5. **无水印打印**:绿色版的FastReport.Net在打印...

    在.Net6中调用IronPython实现动态执行脚本

    在.NET 6中调用IronPython来实现动态执行脚本是一项强大的功能,它允许程序员在运行时编写和执行Python代码,极大地增强了应用的灵活性。IronPython是一个开源的Python实现,它能够无缝集成到.NET环境中,使得.NET...

    如何向IIS注册ASP.NET

    7. `-lk`:列出具有ASP.NET脚本映射的所有IIS元数据库项的路径和版本。 8. `-lv`:显示所有已安装的ASP.NET版本的状态和安装路径。 9. `-r`:更新所有脚本映射以指向Aspnet_regiis.exe关联的ASP.NET ISAPI版本,...

    ColorPicker 好用的asp.net颜色选择控件

    - **脚本之家.url**:可能是一个链接,指向一个专门讨论ASP.NET脚本或Web开发的社区网站,用户可以在那里获取更多关于ColorPicker控件的讨论和示例代码。 - **服务器软件.url**:这可能是关于服务器软件的链接,可能...

    Lua开发包 for Script.NET V2.1.1

    Lua开发包是Script.NET脚本语言开发平台的Lua插件,必须先安装Script.NET平台V2.1.1版本,然后再安装此开发包。 Script.NET平台下载地址:http://download.csdn.net/source/1034307 ... Script.NET是蓝蚂蚁工作室开发的...

    Tcl开发包 for Script.NET V2.1.1

    Tcl开发包是Script.NET脚本语言开发平台的Tcl插件,必须先安装Script.NET平台V2.1.1版本,然后再安装此开发包。 Script.NET平台下载地址:http://download.csdn.net/source/1034307 ... Script.NET是蓝蚂蚁工作室开发的...

Global site tag (gtag.js) - Google Analytics