NScript - A script host for C#/VB.NET/JScript.NET(NScript-.Net语言的脚步解释主机)

原文链接:

http://www.codeproject.com/Articles/3207/NScript-A-script-host-for-C-VB-NET-JScript-NET

安装包和源代码下载链接:

(原文页面提供文件下载链接,CodeProject下载文件需要注册账户,鄙人将文件转存到CSDN上,方便CSDN用户下载)

http://download.csdn.net/detail/eyuanatqqdotcom/4489723

Introduction

NScript is a tool similar to WScript except that it allows scripts to be written in .NET languages such as C#, VB.NET and JScript.NET. NScript automatically compiles the code into an assembly in memory and executes the assembly. The NScript setup application associates NScript with ".ncs" (for C# scripts), ".nvb" (for VB.NET scripts) and ".njs" (for JScript .NET scripts) file extensions. This enables any code written in these files to be executed directly by double clicking on these files in windows explorer. I wrote this tool when I needed to write a script for automating builds. A simple batch file was not sufficient for the task and I preferred to write code in C# as opposed to VBScript or JScript. This tool came in handy as I could modify the scripts easily and execute them by double clicking on the files in windows explorer.

NScript类似于WScipt,但它允许.Net平台语言,例如C#、VB.Net、JScript.Net等。

NScript会自动地将.Net代码(CLI中间语言代码)编译为汇编代码,并在内存中执行。

NScript安装应用程序,文件类型和扩展名关联方式为.ncs为C#脚本代码,.nvb为VB.Net脚本代码,.njs为JScript脚步代码。

安装好NScript后,在以上脚本文件中写的代码,可通过简单的双击即可执行。

我在写一个自动构建脚本的时候,写了这个工具。

。。。

使用 NScript

下载并解压安装包。

运行安装程序NScript.msi.

运行msi文件前,确保机器安装有windows installer 和.net框架。

安装文件自动将后缀名为".ncs", ".nvb" 和 ".njs"的文件和NScript程序管理。

写一些代码,例如以下的C#代码。

using System.Windows.Forms;

class Test
{
    static void Main(string[] args)
    {
        MessageBox.Show("Hello World!", "NScript");
    }
};

保存以上代码,文件命名使用后缀名.ncs。

你可以以以下的几种方式执行文件中的代码:

  1. Double click on the file in windows explorer in that case the script is launched using NScriptW
  2. At the command prompt type NScript MessageBox.ncs
  3. At the command prompt type NScriptw MessageBox.ncs
  4. You can execute code written in VB.NET or JScript.NET too. You need to save VB.NET files with the extension ".nvb" and JScript.NET files with extension ".njs"

在命令行模式下运行程序的时候,使用Ctrl+C 或者 Ctrl+Break来结束运行,以窗体程序来执行时,字系统托盘处有一个图标,双击图标则可取消程序的运行。

 

NScript运行的代码需要具备以下条件:

代码必须有类的定义。(变量和方法代码存放在一个类中)

类需要包含一个Main方法,该方法只有一个参数,类型为字符串数组。

可以在NScript.nrf文件中添加任意引用。

该文件和NScript.exe文件位于同一目录下。

以下是一个NScript.nrf文件的内容。

System.Web.dll
System.Web.RegularExpressions.dll
System.Web.Services.dll
System.Windows.Forms.Dll
System.XML.dll

文件每一行是一个dll文件名称。

 

NScript工作原理。

NScript解决方案包含一下三个项目:

NScript - C# 控制台应用程序

NScriptW - C# 窗体应用程序

NScriptLib -  C# 类库

NScript 和 NScriptW 很相似。the former can be used to run scripts that can output to console. NScript shows error messages in console where as NSCriptW shows error messages using message boxes. It is NScriptW which is associated with file extensions. Since there is lot of code that is shared by the two executables the common code is compiled in NScriptLib and both the executables refer to this class library.

The code behind NScript is pretty simple :-

  1. NScript creates an asynchronous delegate that does the compilation and execution asynchronously.
    CompileAndExecuteRoutine asyncDelegate = new 
        CompileAndExecuteRoutine(this.CompileAndExecute);
    
    IAsyncResult result = asyncDelegate.BeginInvoke(fileName, 
        newargs, this, null, null);
    
    //For a windows app a message loop and for a 
    // console app a simple wait
    ExecutionLoop(result);
    
    asyncDelegate.EndInvoke(result);
    
  2. The compilation and execution routine creates a separate AppDomain where it does the main compilation and execution. This is done because the user may require to cancel the execution of he script, in that case theAppDomain can simply be unloaded.
    //Create an AppDomain to compile and execute the code
    //This enables us to cancel the execution if needed
    executionDomain = AppDomain.CreateDomain("ExecutionDomain");
    
    IScriptManager manager = (IScriptManager)
        executionDomain.CreateInstanceFromAndUnwrap(
            typeof(BaseApp).Assembly.Location, 
            typeof(ScriptManager).FullName); 
    
    manager.CompileAndExecuteFile(file, args, this);
    

    IScriptManager interface is implemented by the type ScriptManager. Since any object has to be marshaled in order for it to be referenced from a separateAppDomain, we need the interface IScriptManager (as opposed to directly using theScriptManager object). The ScriptManager type extends theMarshalByRefObject as it is marshaled by reference.

    public class ScriptManager : MarshalByRefObject, IScriptManager
    
  3. The main compilation and execution is carried out by the ScriptManager object'sCompileAndExecute method. It used CodeDOM to carry out the compilation. It first figures out theCodeDomProvider to use based on the extension of the input script file
    //Currently only csharp scripting is supported
    CodeDomProvider provider;
    
    string extension = Path.GetExtension(file);
    
    switch(extension)
    {
    case ".cs":
    case ".ncs":
        provider = new Microsoft.CSharp.CSharpCodeProvider();
        break;
    case ".vb":
    case ".nvb":
        provider = new Microsoft.VisualBasic.VBCodeProvider();
        break;
    case ".njs":
    case ".js":
        provider = (CodeDomProvider)Activator.CreateInstance(
            "Microsoft.JScript", 
            "Microsoft.JScript.JScriptCodeProvider").Unwrap();
        break;
    default:
        throw new UnsupportedLanguageExecption(extension);
    }
    
  4. Once we have a CodeDomProvider we can compile the file into a temporary assembly using theICodeCompiler interface
    System.CodeDom.Compiler.ICodeCompiler compiler = 
        provider.CreateCompiler();
    
    System.CodeDom.Compiler.CompilerParameters compilerparams = 
        new System.CodeDom.Compiler.CompilerParameters();
    
    compilerparams.GenerateInMemory = true;
    compilerparams.GenerateExecutable = true;
    
    System.CodeDom.Compiler.CompilerResults results = 
        compiler.CompileAssemblyFromFile(compilerparams, file);
    
  5. And finally the entry point method of the just compiled assembly is invoked.
    results.CompiledAssembly.EntryPoint.Invoke(
        null, BindingFlags.Static, null, new object[]{args}, null);
    

Conclusion

This is a very simple tool and I must confess that this is in no way an original idea. Don Box wrote a similar tool long time back but I could not locate it. As a result I decided to write my own. In future I hope to enhance it by allowing to compile and execute XML files similar to ".wsh" files. As usual any suggestions are welcome.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值