C#发现之旅:于动态编译的VB.NET脚本引擎(上)
2010-09-30 21:08:18 来源:WEB开发网ReferencedAssemblies保存了编辑脚本时使用的程序集,在初始化脚本引擎时,系统已经默认向该列表添加了mscorlib.dll、System.dll、System.Data.dll、System.Xml.dll、System.Drawing.dll、System.Windows.Forms.dll、Microsoft.VisualBasic.dll等.NET框架标准程序集,用户可以使用该属性添加第三方程序集来增强脚本引擎的功能。
在前面的说明中,为了实现全局对象和全局函数,需要在VB.NET编译器的命令上中使用imports指令导入全局对象和全局函数所在的名称空间,为此笔者定义了一个VBCompilerImports的属性来保存这些名称空间,定义该属性的代码如下
/// <summary>
/// VB编译器使用的名称空间导入
/// </summary>
private StringCollection myVBCompilerImports = new StringCollection();
/// <summary>
/// VB编译器使用的名称空间导入
/// </summary>
public StringCollection VBCompilerImports
{
get
{
return myVBCompilerImports;
}
}
在初始化脚本引擎时程序会在VBCompilerImports列表中添加默认的名称空间Microsoft.VisualBasic。
准备和执行编译的脚本代码和一些参数后,脚本引擎就来编译脚本代码生成临时程序集了,笔者使用以下的代码来进行编译操作
// 检查程序集缓存区
myAssembly = (System.Reflection.Assembly)myAssemblies[strRuntimeSource];
if (myAssembly == null)
{
// 设置编译参数
this.myCompilerParameters.GenerateExecutable = false;
this.myCompilerParameters.GenerateInMemory = true;
this.myCompilerParameters.IncludeDebugInformation = true;
if (this.myVBCompilerImports.Count > 0)
{
// 添加 imports 指令
System.Text.StringBuilder opt = new System.Text.StringBuilder();
foreach (string import in this.myVBCompilerImports)
{
if (opt.Length > 0)
{
opt.Append(",");
}
opt.Append(import.Trim());
}
opt.Insert(0, " /imports:");
for (int iCount = 0; iCount < this.myVBCompilerImports.Count; iCount++)
{
this.myCompilerParameters.CompilerOptions = opt.ToString();
}
}//if
if (this.bolOutputDebug)
{
// 输出调试信息
System.Diagnostics.Debug.WriteLine(" Compile VBA.NET script "r"n" + strRuntimeSource);
foreach (string dll in this.myCompilerParameters.ReferencedAssemblies)
{
System.Diagnostics.Debug.WriteLine("Reference:" + dll);
}
}
// 对VB.NET代码进行编译
Microsoft.VisualBasic.VBCodeProvider provider = new Microsoft.VisualBasic.VBCodeProvider();
#if DOTNET11
// 这段代码用于微软.NET1.1
ICodeCompiler compiler = provider.CreateCompiler();
CompilerResults result = compiler.CompileAssemblyFromSource(
this.myCompilerParameters,
strRuntimeSource );
#else
// 这段代码用于微软.NET2.0或更高版本
CompilerResults result = provider.CompileAssemblyFromSource(
this.myCompilerParameters,
strRuntimeSource);
#endif
// 获得编译器控制台输出文本
System.Text.StringBuilder myOutput = new System.Text.StringBuilder();
foreach (string line in result.Output)
{
myOutput.Append(""r"n" + line);
}
this.strCompilerOutput = myOutput.ToString();
if (this.bolOutputDebug)
{
// 输出编译结果
if (this.strCompilerOutput.Length > 0)
{
System.Diagnostics.Debug.WriteLine("VBAScript Compile result" + strCompilerOutput);
}
}
provider.Dispose();
if (result.Errors.HasErrors == false)
{
// 若没有发生编译错误则获得编译所得的程序集
this.myAssembly = result.CompiledAssembly;
}
if (myAssembly != null)
{
// 将程序集缓存到程序集缓存区中
myAssemblies[strRuntimeSource] = myAssembly;
}
}
更多精彩
赞助商链接