Generieren von Quellcode und Kompilieren eines Programms aus einem CodeDOM-Diagramm

Der System.CodeDom.Compiler-Namespace enthält Schnittstellen zum Generieren von Quellcode aus CodeDOM-Objektdiagrammen und zum Verwalten der Kompilierung mit unterstützten Compilern. Ein Codeanbieter kann Quellcode in einer bestimmten Programmiersprache entsprechend einem CodeDOM-Diagramm erstellen. Eine von CodeDomProvider abgeleitete Klasse kann normalerweise Methoden bereitstellen, durch die Code für die vom Anbieter unterstützte Sprache generiert und kompiliert wird.

Verwenden eines CodeDOM-Codeanbieters zum Generieren von Quellcode

Zum Generieren von Quellcode in einer bestimmten Sprache benötigen Sie ein CodeDOM-Diagramm, das die Struktur des zu generierenden Quellcodes darstellt.

Im folgenden Beispiel wird veranschaulicht, wie eine Instanz von CSharpCodeProvider erstellt wird:

Dim provider As New CSharpCodeProvider()
CSharpCodeProvider provider = new CSharpCodeProvider();

Das Diagramm für die Codegenerierung befindet sich i. d. R. in einer CodeCompileUnit. Zum Generieren von Code für eine CodeCompileUnit, die ein CodeDOM-Diagramm enthält, rufen Sie die GenerateCodeFromCompileUnit-Methode des Codeanbieters auf. Diese Methode enthält einen Parameter für einen TextWriter, der zum Generieren des Quellcodes verwendet wird, sodass in einigen Fällen zunächst ein TextWriter erstellt werden muss, in den geschrieben werden kann. Das folgende Beispiel veranschaulicht das Generieren von Code aus einer CodeCompileUnit und das Schreiben des generierten Quellcodes in eine Datei mit der Bezeichnung HelloWorld.cs.

Public Shared Function GenerateCSharpCode( _
    compileunit As CodeCompileUnit) As String
       
    ' Generate the code with the C# code provider.
    Dim provider As CSharpCodeProvider = New CSharpCodeProvider()

    ' Build the output file name.
    Dim sourceFile As String
    If provider.FileExtension.StartsWith(".")
        sourceFile = "HelloWorld" + provider.FileExtension
    Else
        sourceFile = "HelloWorld." + provider.FileExtension
    End If

    ' Create a TextWriter to a StreamWriter to an output file.
    Dim tw As New IndentedTextWriter( _
        New StreamWriter(sourceFile, False), "    ")

    ' Generate source code using the code provider.
    provider.GenerateCodeFromCompileUnit(compileunit, tw, _
        New CodeGeneratorOptions())

    ' Close the output file.
    tw.Close()
        
    Return sourceFile
End Function
   
public static String GenerateCSharpCode(CodeCompileUnit compileunit)
{
    // Generate the code with the C# code provider.
    CSharpCodeProvider provider = new CSharpCodeProvider();

    // Build the output file name.
    String sourceFile;
    if (provider.FileExtension[0] == '.')
    {
        sourceFile = "HelloWorld" + provider.FileExtension;
    }
    else 
    {
        sourceFile = "HelloWorld." + provider.FileExtension;
    }

    // Create a TextWriter to a StreamWriter to the output file.
    IndentedTextWriter tw = new IndentedTextWriter(
            new StreamWriter(sourceFile, false), "    ");
            
    // Generate source code using the code provider.
    provider.GenerateCodeFromCompileUnit(compileunit, tw, 
            new CodeGeneratorOptions());

    // Close the output file.
    tw.Close();            

    return sourceFile;
}
   

Verwenden eines CodeDOM-Codeanbieters zum Kompilieren von Assemblys

Aufrufen der Kompilierung

Zum Kompilieren einer Assembly mithilfe eines CodeDom-Anbieters benötigen Sie entweder in einer Sprache zu kompilierenden Quellcode, für die ein Compiler vorhanden ist, oder ein CodeDOM-Diagramm, aus dem der zu kompilierende Quellcode generiert werden kann.

Wenn Sie aus einem CodeDOM-Diagramm kompilieren, übergeben Sie CodeCompileUnit mit dem Diagramm an die CompileAssemblyFromDom-Methode des Codeanbieters. Bei einer Quellcodedatei in einer vom Compiler unterstützten Sprache übergeben Sie der CompileAssemblyFromFile-Methode des CodeDom-Anbieters den Namen der Datei, die den Quellcode enthält. Sie können der CompileAssemblyFromSource-Methode des CodeDom-Anbieters auch eine Zeichenfolge übergeben, die den Quellcode in einer vom Compiler unterstützten Sprache enthält.

Konfigurieren von Kompilierungsparametern

Alle Standardmethoden zum Kompilierungsaufruf eines CodeDom-Anbieters enthalten einen Parameter vom Typ CompilerParameters, der die Optionen angibt, die zum Kompilieren verwendet werden.

In der OutputAssembly-Eigenschaft von CompilerParameters können Sie einen Dateinamen für die Ausgabeassembly angeben. Andernfalls wird ein Standardname für die Ausgabedatei verwendet.

Beim Initialisieren einer neuen Instanz von CompilerParameters wird die GenerateExecutable-Eigenschaft standardmäßig auf false festgelegt. Wenn Sie ein ausführbares Programm kompilieren, müssen Sie die GenerateExecutable-Eigenschaft auf true festlegen. Wenn GenerateExecutable auf false festgelegt ist, generiert der Compiler eine Klassenbibliothek.

Wenn Sie eine ausführbare Datei aus einem CodeDOM-Diagramm kompilieren, muss im Diagramm eine CodeEntryPointMethod definiert sein. Wenn mehrere Codeeinstiegspunkte vorhanden sind, muss die MainClass -Eigenschaft von CompilerParameters möglicherweise auf den Namen der Klasse festgelegt werden, die den zu verwendenden Einstiegspunkt definiert.

Um Debuginformationen in eine generierte ausführbare Datei einzufügen, legen Sie die IncludeDebugInformation-Eigenschaft auf true fest.

Wenn das Projekt Verweise auf Assemblys enthält, müssen Sie für die ReferencedAssemblies-Eigenschaft der beim Aufruf der Kompilierung verwendeten CompilerParameters die Assemblynamen als Elemente in einer StringCollection angeben.

Sie können eine Assembly kompilieren, die nicht auf den Datenträger, sondern in den Speicher geschrieben wird, wenn Sie die GenerateInMemory-Eigenschaft auf true festlegen. Wenn eine Assembly im Speicher generiert wird, kann der Code aus der CompiledAssembly-Eigenschaft von CompilerResults einen Verweis auf die generierte Assembly abrufen. Wenn eine Assembly auf einen Datenträger geschrieben wird, können Sie aus der PathToAssembly-Eigenschaft von CompilerResults den Pfad zur generierten Assembly abrufen.

Um eine benutzerdefinierte Zeichenfolge für Befehlszeilenargumente anzugeben, die beim Aufruf der Kompilierung verwendet wird, legen Sie die Zeichenfolge in der CompilerOptions-Eigenschaft fest.

Wenn für den Aufruf der Kompilierung ein Win32-Sicherheitstoken erforderlich ist, geben Sie das Token in der UserToken-Eigenschaft an.

Um in der kompilierten Assembly eine Verknüpfung für eine Win32-Ressourcendatei zu erstellen, geben Sie den Namen der Win32-Ressourcendatei in der Win32Resource-Eigenschaft an.

Wenn Sie eine Warnstufe zum Abbruch der Kompilierung angeben möchten, legen Sie die WarningLevel-Eigenschaft auf eine ganze Zahl fest, die die Warnstufe zum Abbruch der Kompilierung darstellt. Sie können den Compiler auch für den Abbruch der Kompilierung beim Auftreten von Warnungen konfigurieren, indem Sie die TreatWarningsAsErrors-Eigenschaft auf true festlegen.

Das folgende Codebeispiel veranschaulicht die Kompilierung einer Quelldatei mithilfe eines CodeDom-Anbieters, der von der CodeDomProvider-Klasse abgeleitet wurde.

Public Shared Function CompileCSharpCode(sourceFile As String, _
    exeFile As String) As Boolean
    Dim provider As CSharpCodeProvider = New CSharpCodeProvider()
          
    ' Build the parameters for source compilation.
    Dim cp As New CompilerParameters()
         
    ' Add an assembly reference.
    cp.ReferencedAssemblies.Add("System.dll")

    ' Save the assembly as a physical file.
    cp.GenerateInMemory = False

    ' Generate an executable instead of a class library.
    cp.GenerateExecutable = True
          
    ' Set the assembly file name to generate.
    cp.OutputAssembly = exeFile
        
    ' Invoke compilation.
    Dim cr As CompilerResults = _
        provider.CompileAssemblyFromFile(cp, sourceFile)
          
    If cr.Errors.Count > 0 Then
        ' Display compilation errors.
        Console.WriteLine("Errors building {0} into {1}", _
            sourceFile, cr.PathToAssembly)
        Dim ce As System.CodeDom.Compiler.CompilerError
        For Each ce In  cr.Errors
            Console.WriteLine("  {0}", ce.ToString())
            Console.WriteLine()
        Next ce
    Else
        Console.WriteLine("Source {0} built into {1} successfully.", _
            sourceFile, cr.PathToAssembly)
    End If
          
    ' Return the results of compilation.
    If cr.Errors.Count > 0 Then
        Return False
    Else
        Return True
    End If
End Function
public static bool CompileCSharpCode(String sourceFile, 
    String exeFile)
{
    CSharpCodeProvider provider = new CSharpCodeProvider();

    // Build the parameters for source compilation.
    CompilerParameters cp = new CompilerParameters();

    // Add an assembly reference.
    cp.ReferencedAssemblies.Add( "System.dll" );

    // Generate an executable instead of 
    // a class library.
    cp.GenerateExecutable = true;

    // Set the assembly file name to generate.
    cp.OutputAssembly = exeFile;

    // Save the assembly as a physical file.
    cp.GenerateInMemory = false;
 
    // Invoke compilation.
    CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile);

    if(cr.Errors.Count > 0)
    {
        // Display compilation errors.
        Console.WriteLine("Errors building {0} into {1}",  
            sourceFile, cr.PathToAssembly);
        foreach(CompilerError ce in cr.Errors)
        {
            Console.WriteLine("  {0}", ce.ToString());
            Console.WriteLine();
        }
    }
    else
    {
        Console.WriteLine("Source {0} built into {1} successfully.",
            sourceFile, cr.PathToAssembly);
    }
          
    // Return the results of compilation.
    if (cr.Errors.Count > 0)
    {
        return false;
    }
    else 
    {
        return true;
    }
}

Von Beginn an unterstützte Sprachen

.NET Framework bietet Codecompiler und Codegeneratoren für folgende Sprachen: C#, Visual Basic, C++, J# und JScript. Die CodeDOM-Unterstützung kann auf andere Sprachen erweitert werden, indem sprachspezifische Code-Generatoren und Codecompiler implementiert werden.

Siehe auch

Referenz

Kurzreferenz zum CodeDOM
System.CodeDom
System.CodeDom.Compiler

Weitere Ressourcen

Fortgeschrittene Entwicklungstechnologien