編譯參數與 Imports 設定
GenerateExecutable = false、GenerateInMemory = true、IncludeDebugInformation = true
- VB 編譯器
/imports 參數指定全域命名空間,格式:/imports:ns1,ns2
- 與原始碼中
Imports 語句不同,命令列參數影響整個編譯單元
動態編譯核心代碼
myAssembly = (Assembly)myAssemblies[strRuntimeSource];
if (myAssembly == null) {
myCompilerParameters.GenerateExecutable = false;
myCompilerParameters.GenerateInMemory = true;
myCompilerParameters.IncludeDebugInformation = true;
if (myVBCompilerImports.Count > 0) {
StringBuilder opt = new StringBuilder();
foreach (string imp in myVBCompilerImports) {
if (opt.Length > 0) opt.Append(",");
opt.Append(imp.Trim());
}
opt.Insert(0, " /imports:");
myCompilerParameters.CompilerOptions = opt.ToString();
}
if (bolOutputDebug) {
Debug.WriteLine("Compile VBA.Net script \r\n" + strRuntimeSource);
foreach (string dll in myCompilerParameters.ReferencedAssemblies)
Debug.WriteLine("Reference:" + dll);
}
VBCodeProvider provider = new VBCodeProvider();
#if DOTNET11
ICodeCompiler compiler = provider.CreateCompiler();
CompilerResults result = compiler.CompileAssemblyFromSource(myCompilerParameters, strRuntimeSource);
#else
CompilerResults result = provider.CompileAssemblyFromSource(myCompilerParameters, strRuntimeSource);
#endif
StringBuilder output = new StringBuilder();
foreach (string line in result.Output) output.Append("\r\n" + line);
strCompilerOutput = output.ToString();
if (bolOutputDebug && strCompilerOutput.Length > 0)
Debug.WriteLine("VBAScript Compile result" + strCompilerOutput);
provider.Dispose();
if (!result.Errors.HasErrors) myAssembly = result.CompiledAssembly;
if (myAssembly != null) myAssemblies[strRuntimeSource] = myAssembly;
}
關鍵點
- 使用靜態
Hashtable myAssemblies 快取編譯結果,相同腳本文字重複編譯直接取用
- 相容 .NET 1.1 與 2.0+ 兩套編譯 API
- 編譯錯誤不拋出例外,透過
CompilerResults.Errors 判斷
- 編譯輸出文字保存於
strCompilerOutput 供診斷