vb.net执行脚本 如何执行vbs脚本

如何在.NET中实现脚本引擎

NET 本身提供了强大的脚本引擎,可以直接使用.NET CLR的任何编程语言作为脚本语言,如VB.NET、C#、JScript, J#等等。使用脚本引擎,我们可以动态生成任意表达式、或动态导入任意脚本文件,并在任意时候执行。

网站设计制作、成都网站设计过程中,需要针对客户的行业特点、产品特性、目标受众和市场情况进行定位分析,以确定网站的风格、色彩、版式、交互等方面的设计方向。创新互联还需要根据客户的需求进行功能模块的开发和设计,包括内容管理、前台展示、用户权限管理、数据统计和安全保护等功能。

经实践发现,我们可以使用至少两种不同的方式在.NET中使用脚本引擎:VsaEngine和CodeDom。

其实,CodeDom不能算是真正的脚本引擎,它实际上是编译器。但是我们完全可以利用CodeDom来模拟脚本引擎。

使用Emit方法也能达到动态生成可执行代码的目的,而且Emit生成的代码不需要编译,因此速度更快。但是Emit插入的实际上是汇编代码,不能算是脚本语言。

本文介绍如何以CodeDom方式来动态生成可执行代码。

如何在.NET中实现脚本引擎 (CodeDom篇) 沐枫网志

1. 构造一个编译器

设置编译参数

编译参数需要在CompilerParameters设置:

CompilerOptions 用于设置编译器命令行参数

IncludeDebugInformation 用于指示是否在内存在生成Assembly

GenerateInMemory 用于指示是否在内存在生成Assembly

GenerateExecutable 用于指示生成的Assembly类型是exe还是dll

OutputAssembly 用于指示生成的程序文件名(仅在GenerateInMemory为false的情况)

ReferencedAssemblies 用于添加引用Assembly

例如:

theParameters.ReferencedAssemblies.Add("System.dll");

创建指定语言的编译器

编译需要由指定语言的CodeDomProvider生成。

这里列举一些.NET的CodeDomProvider:

vb.net Microsoft.VisualBasic.VBCodeProvider

C# Microsoft.CSharp.CSharpCodeProvider

jscript Microsoft.JScript.JScriptCodeProvider

J# Microsoft.VJSharp.VJSharpCodeProvider

以C#为例,要创建C#编译器,代码如下:

//.NET 1.1/1.0

ICodeCompiler compiler = new Microsoft.CSharp.CSharpCodeProvider().CreateCompiler();

//.NET 2.0

ICodeCompiler compiler = (ICodeCompiler) new Microsoft.CSharp.CSharpCodeProvider();

下面是完整的创建编译器的例子:

/// summary

/// 创建相应脚本语言的编译器

/// /summary

private void createCompiler(string strLanguage, bool debugMode, string strAssemblyFileName)

{

this.theParameters = new CompilerParameters();

this.theParameters.OutputAssembly = System.IO.Path.Combine(System.IO.Path.GetTempPath(), strAssemblyFileName + ".dll");

this.theParameters.GenerateExecutable = false;

this.theParameters.GenerateInMemory = true;

if(debugMode)

{

this.theParameters.IncludeDebugInformation = true;

this.theParameters.CompilerOptions += "/define:TRACE=1 /define:DEBUG=1 ";

}

else

{

this.theParameters.IncludeDebugInformation = false;

this.theParameters.CompilerOptions += "/define:TRACE=1 ";

}

AddReference("System.dll");

AddReference("System.Data.dll");

AddReference("System.Xml.dll");

strLanguage = strLanguage.ToLower();

CodeDomProvider theProvider;

if("visualbasic" == strLanguage || "vb" == strLanguage)

{

theProvider = new Microsoft.VisualBasic.VBCodeProvider();

if(debugMode)

theParameters.CompilerOptions += "/debug:full /optimize- /optionexplicit+ /optionstrict+ /optioncompare:text /imports:Microsoft.VisualBasic,System,System.Collections,System.Diagnostics ";

else

theParameters.CompilerOptions += "/optimize /optionexplicit+ /optionstrict+ /optioncompare:text /imports:Microsoft.VisualBasic,System,System.Collections,System.Diagnostics ";

AddReference("Microsoft.VisualBasic.dll");

}

else if("jscript" == strLanguage || "js" == strLanguage)

{

theProvider = new Microsoft.JScript.JScriptCodeProvider();

AddReference("Microsoft.JScript.dll");

}

else if("csharp" == strLanguage || "cs" == strLanguage || "c#" == strLanguage)

{

theProvider = new Microsoft.CSharp.CSharpCodeProvider();

if(!debugMode)

theParameters.CompilerOptions += "/optimize ";

}

// else if("jsharp" == strLanguage || "vj" == strLanguage || "j#" == strLanguage)

// {

// theProvider = new Microsoft.VJSharp.VJSharpCodeProvider();

// if(!debugMode)

// theParameters.CompilerOptions += "/optimize ";

// }

else

throw new System.Exception("指定的脚本语言不被支持。");

this.theCompiler = theProvider.CreateCompiler();

}

/// summary

/// 添加引用对象。

/// /summary

/// param name="__strAssemblyName"引用的文件名/param

public void AddReference(string __strAssemblyName)

{

theParameters.ReferencedAssemblies.Add(__strAssemblyName);

}

注:

在.NET Framework 2.0中,由于CreateCompiler方法被标记作废。为避免产生编译警告,可直接返回CodeDomProvider作为编译器:

this.theCompiler = (ICodeCompiler)theProvider;

2. 编译源代码

编译源代码相当简单,只需一条语句就搞定了:

CompilerResults compilerResults = compiler.CompileAssemblyFromSource(this.theParameters, this.SourceText);

执行后,可以从compilerResults取得以下内容:

NativeCompilerReturnValue 编译结果,用于检查是否成功

Errors 编译时产生的错误和警告信息

CompiledAssembly 如果编译成功,则返回编译生成的Assembly

示例函数:

/// summary

/// 编译脚本。编译前将清空以前的编译信息。

/// CompilerInfo将包含编译时产生的错误信息。

/// /summary

/// returns成功时返回True。不成功为False。/returns

public bool Compile()

{

this.theCompilerInfo = "";

this.isCompiled = false;

this.theCompiledAssembly = null;

this.theCompilerResults = this.theCompiler.CompileAssemblyFromSource(this.theParameters, this.SourceText);

if(this.theCompilerResults.NativeCompilerReturnValue == 0)

{

this.isCompiled = true;

this.theCompiledAssembly = this.theCompilerResults.CompiledAssembly;

}

System.Text.StringBuilder compilerInfo = new System.Text.StringBuilder();

foreach(CompilerError err in this.theCompilerResults.Errors)

{

compilerInfo.Append(err.ToString());

compilerInfo.Append("/r/n");

}

theCompilerInfo = compilerInfo.ToString();

return isCompiled;

}

3. 执行代码

使用Reflection机制就可以很方便的执行Assembly中的代码。

我们假设编译时使用的脚本代码 this.SourceText 内容如下:

namespace test

{

public class script

{

static public void Main()

{

MessageBox.Show("Hello");

}

}

}

则相应的执行代码为:

scriptEngine.Invoke("test.script", "Main", null);

Invoke函数内容:

/// summary

/// 执行指定的脚本函数(Method)。

/// 如果指定的类或模块名,以及函数(Method)、或参数不正确,将会产生VsaException/VshException例外。

/// /summary

/// param name="__strModule"类或模块名/param

/// param name="__strMethod"要执行的函数(Method)名字/param

/// param name="__Arguments"参数(数组)/param

/// returns返回执行的结果/returns

public object Invoke(string __strModule, string __strMethod, object[] __Arguments)

{

if(!this.IsCompiled || this.theCompiledAssembly == null)

throw new System.Exception("脚本还没有成功编译");

Type __ModuleType = this.theCompiledAssembly.GetType(__strModule);

if(null == __ModuleType)

throw new System.Exception(string.Format("指定的类或模块 ({0}) 未定义。", __strModule));

MethodInfo __MethodInfo = __ModuleType.GetMethod(__strMethod);

if(null == __MethodInfo)

throw new System.Exception(string.Format("指定的方法 ({0}::{1}) 未定义。", __strModule, __strMethod));

try

{

return __MethodInfo.Invoke(null, __Arguments);

}

catch( TargetParameterCountException )

{

throw new System.Exception(string.Format("指定的方法 ({0}:{1}) 参数错误。", __strModule, __strMethod));

}

catch(System.Exception e)

{

System.Diagnostics.Trace.WriteLine(string.Format("执行({0}:{1})错误: {2}", __strModule, __strMethod, e.ToString()));

return null;

}

}

总结:

CodeDom可以很方便的随时编译源代码,并动态执行。虽然作为脚本引擎,它没有VsaEngine正规和方便,但作为一般应用,也够用了。并且结合Reflection机制,它的功能比VsaEngine更强大:它可以编译任何提供CompilerProvider的CLR语言(目前.NET自带的语言中都有)。

当然,它也有一些缺点:它生成的Assembly不能动态卸载。这在一般情况下不成问题,因为一个源代码只需编译一次,并载入执行,并不需要动态卸载。

假如你需要做脚本编辑器时,就要考虑这个问题,因为有可能一个脚本会因为修修改改而不停的重新编译,从而造成不停的产生新的Assembly,最后将导致内存被大量占用。要解决这个问题,需要将编译器加载到独立的AppDomain中,通过卸载AppDomain达到卸载所需的Assembly的目的。

VBS和vb.net运行平台的问题

vbs是解释执行的,在网页上运行的一般用的是 IE的库,或者是ASP的库,直接改后缀那种用的是mscrpt 的库,所以很多对象是不能通用的

VB.net 编写的程序当然可以XP上运行,但是要用到.NET的库,就是要装相应版本的net framework 才可以运行!

vb.net 如何运行javascript

既然引用了COM组件,就可以直接使用了,无需用CreateObject创建。

Dim ScriptControl As New MSScriptControl.ScriptControl

ScriptControl.Language = "JavaScript" '设置语言种类

ScriptControl.AddCode("function TestFunc(){return 'Hello world!'}") '添加脚本代码

MsgBox(ScriptControl.Run("TestFunc")) '显示一下那段脚本的返回值(这里你将看到Hello world!字符)

vb.net WebBrowser 控件如何执行Script

部分代码如下:

在窗口及WebBrowser创建完以后,写此代码:

WebBrowser.OnNewWindow2:=IE1NewWindow2;

给主窗口创建一个方法:

procedure TBrowForm.IE1NewWindow2(Sender: TObject; var ppDisp: IDispatch;var Cancel: WordBool);

Var NewForm:TBrowForm;

begin

try

NewForm :=TPopBrowerForm.Create(application);

NewForm.WebBrowser.OnNewWindow2 :=IE1NewWindow2;//如果在窗口的Oncreate事件

//有此代码,此处就可以省略

ppDisp := NewForm.WebBrowser.Application;

NewForm.Show;

Cancel:=false;

except

end;

end;

VB.NET可以编写VBS脚本吗

”VBS脚本“可以用任何纯

文本编辑

工具编写,包括系统自带的”记事本“。VB.NET当然也可以。

如果你是需要语法提示之类的,VB.NET可以提供绝大部分的语法提示。毕竟

VBS

VB

的子集。

vb.net是脚本语言吗?

非也,乃微软新一代面向对象可视化编程语言。另外,vb.net和vb6.0及以前版本都有很大差别。属.net平台。.net framework现在最新的版本是3.5,建议你学习2.0版本即可,有机会再看看3.5。


分享标题:vb.net执行脚本 如何执行vbs脚本
文章链接:http://myzitong.com/article/hgddsi.html