2009-05-17 26 views
19

我有一个应用程序,它动态加载c#源文件并将它们作为插件运行。当我在调试模式下运行主应用程序时,是否可以调试到动态程序集?显然,设置断点是有问题的,因为源不是原始项目的一部分,但是我应该能够进入代码的异常还是破解代码的异常?如何在codedom编译代码中调试/中断

有没有办法让codedom为这个或其他东西生成PDB?

这是我用于动态编译的代码。

CSharpCodeProvider codeProvider = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } }); 
//codeProvider. 
ICodeCompiler icc = codeProvider.CreateCompiler(); 

CompilerParameters parameters = new CompilerParameters(); 
parameters.GenerateExecutable = false; 
parameters.GenerateInMemory = true; 
parameters.CompilerOptions = string.Format("/lib:\"{0}\"", Application.StartupPath); 
parameters.ReferencedAssemblies.Add("System.dll"); 
parameters.ReferencedAssemblies.Add("System.Core.dll"); 


CompilerResults results = icc.CompileAssemblyFromSource(parameters, Source); 
DLL.CreateInstance(t.FullName, false, BindingFlags.Default, null, new object[] { engine }, null, null); 
+0

出于好奇(我从来没有真正与CodeDom的东西搞砸)如果你尝试把一个System.Diagnostics.Debugger.Break();在你的代码中的某个地方?你能接着进入吗? – BFree 2009-05-17 23:36:53

+0

这工作,但只有在接受答案的选项。 – 2009-06-04 15:46:03

+0

我无意中重复了这个问题(codedom不是我寻找的关键工作)。 http://stackoverflow.com/questions/1593920/debugging-a-generated-net-assembly-from-within-the-application-that-generated-it/1594910#1594910。我添加了一个涉及界面的解决方案。希望它有帮助... – jdehaan 2009-10-20 14:16:58

回答

31

尝试下列选项:

parameters.GenerateInMemory = false; //default 
parameters.TempFiles = new TempFileCollection(Environment.GetEnvironmentVariable("TEMP"), true); 
parameters.IncludeDebugInformation = true; 

我不知道这是否OK,你的情况,但如果这样做,你可以围绕这个参数与条件编译指令,使其转储生成的程序集仅在调试模式下。

7

answer by @bbmud是正确的,但它错过了一个错误修复。 CSharpCodeGenerator(.NET中的类编译C到IL的C#代码)设置为在创建后立即删除pdb文件,除非您将/debug:pdbonly添加到CompilerOptions字符串中。但是,如果这样做,IncludeDebugInformation标志将被忽略,编译器将生成难以调试的优化代码。为了避免这种情况,您必须明确告诉代码生成器保留所有文件。

下面是完整的配方:

parameters.GenerateInMemory = false; //default 
parameters.TempFiles = new TempFileCollection(Environment.GetEnvironmentVariable("TEMP"), true); 
parameters.IncludeDebugInformation = true; 
parameters.TempFiles.KeepFiles = true 

这里是CSharpCodeGenerator的代码的元凶部分:

string fileExtension = "pdb"; 
    if ((options.CompilerOptions != null) && (CultureInfo.InvariantCulture.CompareInfo.IndexOf(options.CompilerOptions, "/debug:pdbonly", CompareOptions.IgnoreCase) != -1)) 
    { 
     results.TempFiles.AddExtension(fileExtension, true); 
    } 
    else 
    { 
     results.TempFiles.AddExtension(fileExtension); 
    } 

TempFiles.AddExtension(fileExtension, true)告诉编译保持pdb文件。 其他results.TempFiles.AddExtension(fileExtension);选项告诉它将pdb视为默认意味着将其删除的所有临时文件。