.NET 脚本

原创 2004年03月24日 10:05:00

.NET 脚本(一)
作者: jconwell<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

简介

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

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

Dot Net 标记语言

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

该文档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()。这个方法将完成所有的工作,编译并生成一个新的程序集,正如下面所看到的.

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

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

下一步,我创建一个CompilerParameters 对象。这个类基本上包装了当你手工通过csc.exe (C# 编译器) vbc.exe (VB.NET 编译器) 编译一个程序集时所用的所有命令行参数。一个特别重要的参数就是属性GenerateInMemory,  这里我用到了它。它能确保当代码编译时,生成的程序集只会驻存在内存中,而不会作为结果创建任何文件。

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

然后,我调用了CodeCompiler.CompileAssemblyFromSource, 它传入CompilerParameters 对象和包含所要编译的实际代码的字符串变量。返回的对象属于类CompilerResults. 当编译出现错误时,这个对象包含一个CompileError 对象的集合,我将用它显示给用户当编译时那些地方出错了。

如果脚本代码编译成功,CompilerReslts 对象将包含一个对于新编译和创建的程序集的引用。我保留该对象并返回给调用方法。

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

最后一步

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

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

ASP.NET 服务器控件中插入客户端脚本(自定义控件)

用于:Microsoft® ASP.NET前提条件:本文假设读者熟悉 ASP.NET。难度: 2摘要:尽管从技术角度讲,ASP.NET 服务器控件的所有功能都可以在服务器端执行,但通常情况下通过添加客...
  • msnetc
  • msnetc
  • 2006年07月19日 17:45
  • 1973

在asp.net在服务端向客户端添加脚本实现自动弹出消息

在asp.net在服务端向客户端添加脚本实现自动弹出消息原理:  在Asp.Net中,经常需要在客户端提交后,根据提交信息的不同,自动弹出一个不同的消息。所以,就有了在服务端向客户端动态添加脚本实现打...
  • hydonlee
  • hydonlee
  • 2004年09月09日 21:06
  • 2174

.net petstore 安装包最新版本(源码、数据库脚本)

  • 2012年12月03日 10:12
  • 2.31MB
  • 下载

.NET 脚本

.NET 脚本(一)作者: jconwell 简介你知道我对于前.NET时代有什么留恋吗?脚本!我喜欢创建一个小巧的脚本文件为我完成一些小任务,或者为了测试一小段代码而无需创建一项工程或是解决方案。我...
  • greenland
  • greenland
  • 2004年03月24日 10:05
  • 1107

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

Script.NET是一种动态的脚本语言,它使得程序可扩展,可定制,和维护性好。和Office系列的VB Script相似,可以在应用中嵌入大量的代码块,以便在运行时才执行这些代码。 Scrip...
  • Steven_ssm
  • Steven_ssm
  • 2017年08月20日 15:16
  • 156

(喷血分享)利用.NET生成数据库表的创建脚本,类似SqlServer编写表的CREATE语句

在我们RDIFramework.NET代码生成器中,有这样一个应用,就是通过数据库表自动生成表的CREATE语句。 在实现此功能前摸索了很多方法,最后借助MSSQLSERVER自带的dll文件来完成,...
  • chinahuyong
  • chinahuyong
  • 2013年07月25日 15:32
  • 5672

最新.net技术博客源代码

  • 2009年07月16日 09:58
  • 1.89MB
  • 下载

ASP.NET MVC5+EF6+EasyUI 后台管理系统 (源码购买说明)

系列目录 方便朋友获取一个开发框架,无论是开发还是学习用途将受益匪浅,出售此框架源码价格666,终身免费升级,在线解答问题 您可以通过QQ 729994997 联系我 ASP.NET MVC5+E...
  • ymnets
  • ymnets
  • 2017年11月29日 08:44
  • 289

.NET FrameWork中有内置的.NET编译器,可实现.NET程序的脚本支持

    在新版本的产品中,我需要支持脚本,我试过VBA,效果还不错,但是在VC2005中感觉总是不太好,因为我必须将程序中增加很多的COM接口,否则VBA无法使用,但是增加COM接口工作量太大了,而切...
  • sfcyyc
  • sfcyyc
  • 2006年09月29日 13:03
  • 1717

.Net Framework下安装Windows服务的脚本

     最近写了几个Windows后台服务,总要用命令安装,然后又得跑到服务管理里面找出服务,Start,Stop…… 实在是受不了,就写了个脚本,放上来大家有用的话就拿去用吧!安装服务的脚本:  ...
  • hejianhuacn
  • hejianhuacn
  • 2008年06月03日 17:21
  • 1110
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.NET 脚本
举报原因:
原因补充:

(最多只允许输入30个字)