2009-03-02 8 views
28

Obecnie mam pewien kod, który jest generowany dynamicznie. Innymi słowy, plik C# .cs jest tworzony dynamicznie przez program, a intencją jest włączenie tego pliku C# do innego projektu.Generowanie zespołu DLL dynamicznie w czasie wykonywania

Wyzwanie polega na tym, że chciałbym wygenerować plik .DLL zamiast generować plik C# .cs, aby mógł on być przywoływany przez jakąkolwiek aplikację .NET (nie tylko C#) i dlatego byłby bardziej przydatny.

Odpowiedz

37
using System.CodeDom.Compiler; 
using System.Diagnostics; 
using Microsoft.CSharp; 

CSharpCodeProvider codeProvider = new CSharpCodeProvider(); 
ICodeCompiler icc = codeProvider.CreateCompiler(); 
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters(); 
parameters.GenerateExecutable = false; 
parameters.OutputAssembly = "AutoGen.dll"; 
CompilerResults results = icc.CompileAssemblyFromSource(parameters, yourCodeAsString); 

Adaptacja http://support.microsoft.com/kb/304655

+0

UWAGA: starszych wersji tego kodu mają dodatkowy wiersz kodu, który tworzy kompilatora od dostawcy za pomocą CSharpCodeProvider.CreateCompiler(). To jest przestarzałe, powinieneś połączyć się bezpośrednio z dostawcą. –

3

Teraz najlepiej jest CSharpCodeProvider; plany na 4.0 zawierają "kompilator jako usługa", co spowoduje, że będzie on w pełni zarządzany.

+0

tytuł tematu to "generate-dll-assembly-dynamically-at-run-time" NIE "generowanie-EXE-assembly-dynamically-at-run-time" twój opis linku abut create exe w czasie wykonywania. –

+1

@AminGhaderi i kto powiedział coś o exe? Jeśli masz na myśli "ale kod przykładowy na MSDN tworzy exe" - z przyjemnością utworzy również bibliotekę dll; ostatecznie pakiet plików jest * nie * interesującą częścią zestawu –

28

Non-przestarzały sposób to zrobić (przy użyciu .NET 4.0 jak poprzednie plakaty wymienionych):

using System.CodeDom.Compiler; 
using System.Reflection; 
using System; 
public class J 
{ 
    public static void Main() 
    {  
     System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters(); 
     parameters.GenerateExecutable = false; 
     parameters.OutputAssembly = "AutoGen.dll"; 

     CompilerResults r = CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(parameters, "public class B {public static int k=7;}"); 

     //verify generation 
     Console.WriteLine(Assembly.LoadFrom("AutoGen.dll").GetType("B").GetField("k").GetValue(null)); 
    } 
} 
+0

Jeśli użyjesz 'parameters.GenerateInMemory = true;' możesz uzyskać podzbiór w pamięci za pomocą 'r.CompiledAssembly' –