2009-05-17 81 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視爲默認意味着將其刪除的所有臨時文件。