2009-05-17 28 views
19

Ho un'applicazione che carica i file di origine C# in modo dinamico e li esegue come plugin. Quando eseguo l'applicazione principale in modalità di debug, è possibile eseguire il debug nell'assembly dinamico? Ovviamente l'impostazione dei punti di interruzione è problematica, dal momento che la sorgente non fa parte del progetto originale, ma dovrei essere in grado di intervenire o interrompere le eccezioni per il codice?Come eseguire il debug/break in code codice compilato

C'è un modo per ottenere la codifica per generare PDB per questo o qualcosa del genere?

Ecco il codice che sto usando per la compliazione dinamica.

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

Per curiosità (non ho mai veramente incasinato le cose di CodeDom) cosa succede se provi a mettere un System.Diagnostics.Debugger.Break(); da qualche parte nel tuo codice? Puoi quindi entrarci? – BFree

+0

ha funzionato, ma solo con le opzioni nella risposta accettata. –

+0

Ho duplicato questa domanda per inavvertenza (la codifica non era la chiave che cercavo). http://stackoverflow.com/questions/1593920/debugging-a-generated-net-assembly-from-within-the-application-that-generated-it/1594910#1594910. Ho aggiunto una soluzione che implica un'interfaccia. Spero che aiuti ... – jdehaan

risposta

31

provare le seguenti opzioni:

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

Non sono sicuro se questo funziona bene nel tuo caso, ma se lo fa, si può circondare questi parametri con direttiva di compilazione condizionale, in modo da discariche l'assemblaggio generato solo in modalità debug.

+2

Sono passati 2,42 anni, ma voi signore, siete fantastici! – Philip

+0

Ha risparmiato il mio tempo per scoprire il problema :) – superachu

7

Il answer by @bbmud è corretto, anche se manca una correzione di errore. CSharpCodeGenerator (la classe in .NET compila il codice C# in IL) è impostato per rimuovere i file pdb immediatamente dopo la loro creazione, A MENO che tu aggiunga /debug:pdbonly alla stringa CompilerOptions. Tuttavia, se lo fai, il flag IncludeDebugInformation viene ignorato e il compilatore genera codice ottimizzato che è difficile da eseguire il debug. Per evitare ciò devi dire esplicitamente al Generatore di codice di conservare tutti i file.

Ecco la ricetta completa:

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

Qui è la parte colpevole del codice di 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); 
    } 

Il TempFiles.AddExtension(fileExtension, true) dice la compilazione per mantenere i file PDB. L'opzione alternativa di results.TempFiles.AddExtension(fileExtension); indica di trattare pdb come tutti i file temporanei che per impostazione predefinita significa eliminarli.

+0

Il secondo argomento in 'TempFileCollection' (denominato" keepFiles ") imposta già la proprietà' KeepFiles' su true. (o almeno lo fa in .NET 4.0) –

Problemi correlati