Delen via


Broncode genereren en compileren vanuit een CodeDOM-grafiek

De System.CodeDom.Compiler naamruimte biedt interfaces voor het genereren van broncode uit CodeDOM-objectgrafieken en voor het beheren van compilatie met ondersteunde compilers. Een codeprovider kan broncode produceren in een bepaalde programmeertaal volgens een CodeDOM-grafiek. Een klasse die is afgeleid van CodeDomProvider , kan doorgaans methoden bieden voor het genereren en compileren van code voor de taal die de provider ondersteunt.

Een CodeDOM-codeprovider gebruiken om broncode te genereren

Als u broncode in een bepaalde taal wilt genereren, hebt u een CodeDOM-grafiek nodig die de structuur van de broncode vertegenwoordigt om te genereren.

In het volgende voorbeeld demonstreert hoe u een instantie van een CSharpCodeProvider maakt.

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

De grafiek voor het genereren van code bevindt zich meestal in een CodeCompileUnit. Als u code wilt genereren voor een CodeCompileUnit grafiek met CodeDOM, roept u de GenerateCodeFromCompileUnit methode van de codeprovider aan. Deze methode heeft een parameter voor een TextWriter parameter die wordt gebruikt om de broncode te genereren, dus het is soms nodig om eerst een TextWriter parameter te maken waarnaar kan worden geschreven. In het volgende voorbeeld ziet u hoe u code genereert van een CodeCompileUnit en de gegenereerde broncode schrijft naar een bestand met de naam HelloWorld.cs.

public:
    static String^ GenerateCSharpCode(CodeCompileUnit^ compileunit)
    {
        // Generate the code with the C# code provider.
        CSharpCodeProvider^ provider = gcnew 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.
        StreamWriter^ sw = gcnew StreamWriter(sourceFile, false);
        IndentedTextWriter^ tw = gcnew IndentedTextWriter(sw, "    ");

            // Generate source code using namespace the code provider.
        provider->GenerateCodeFromCompileUnit(compileunit, tw,
            gcnew CodeGeneratorOptions());

        // Close the output file.
        tw->Close();
        sw->Close();

        return sourceFile;
    }
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.
    using (StreamWriter sw = new StreamWriter(sourceFile, false))
    {
        IndentedTextWriter tw = new IndentedTextWriter(sw, "    ");

        // Generate source code using the code provider.
        provider.GenerateCodeFromCompileUnit(compileunit, tw,
            new CodeGeneratorOptions());

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

    return sourceFile;
}
Public Shared Function GenerateCSharpCode(compileunit As CodeCompileUnit) As String
    ' Generate the code with the C# code provider.
    Dim provider As New CSharpCodeProvider()

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

    ' Create a TextWriter to a StreamWriter to the output file.
    Using sw As New StreamWriter(sourceFile, false)
        Dim tw As New IndentedTextWriter(sw, "    ")

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

        ' Close the output file.
        tw.Close()
    End Using

    Return sourceFile
End Function

Een CodeDOM-codeprovider gebruiken om assembly's te compileren

Compilatie aanroepen

Als u een assembly wilt compileren met behulp van een CodeDom-provider, moet u de broncode hebben om te compileren in een taal waarvoor u een compiler hebt, of een CodeDOM-grafiek waaruit de broncode kan worden gecompileerd.

Als u vanuit een CodeDOM-grafiek compileert, geeft u de CodeCompileUnit grafiek door aan de CompileAssemblyFromDom methode van de codeprovider. Als u een broncodebestand hebt in een taal die de compiler begrijpt, geeft u de naam van het bestand met de broncode door aan de CompileAssemblyFromFile methode van de CodeDom-provider. U kunt ook een tekenreeks met broncode doorgeven in een taal die de compiler begrijpt bij de CompileAssemblyFromSource methode van de CodeDom-provider.

Compilatieparameters configureren

Alle standaard compilatiemethoden van een CodeDom-provider hebben een parameter van het type CompilerParameters die aangeeft welke opties moeten worden gebruikt voor compilatie.

U kunt een bestandsnaam opgeven voor de uitvoerassembly in de OutputAssembly eigenschap van de CompilerParameters. Anders wordt een standaardnaam voor het uitvoerbestand gebruikt.

Standaard wordt een nieuwe CompilerParameters geïnitialiseerd met de GenerateExecutable eigenschap ingesteld op false. Als u een uitvoerbaar programma compileert, moet u de GenerateExecutable eigenschap instellen op true. Wanneer GenerateExecutable is ingesteld op false, genereert de compiler een klassenbibliotheek.

Als u een uitvoerbaar bestand compileert vanuit een CodeDOM-grafiek, moet een CodeEntryPointMethod bestand worden gedefinieerd in de grafiek. Als er meerdere codeinvoerpunten zijn, kan het nodig zijn om de MainClass eigenschap van de CompilerParameters klasse in te stellen op de naam van de klasse die het te gebruiken toegangspunt definieert.

Als u foutopsporingsinformatie wilt opnemen in een gegenereerd uitvoerbaar bestand, stelt u de IncludeDebugInformation eigenschap in op true.

Als uw project verwijst naar assembly's, moet u de assemblynamen opgeven als items in een StringCollection als de ReferencedAssemblies eigenschap van de CompilerParameters die u gebruikt bij het oproepen van compilatie.

U kunt een assembly compileren die naar het geheugen wordt geschreven in plaats van schijf door de GenerateInMemory eigenschap in te stellen op true. Wanneer een assembly in het geheugen wordt gegenereerd, kan uw code een verwijzing verkrijgen naar de gegenereerde assembly op basis van de CompiledAssembly eigenschap van een CompilerResults. Als een assembly naar de schijf wordt geschreven, kunt u het pad naar de gegenereerde assembly verkrijgen op basis van de PathToAssembly eigenschap van een CompilerResults.

Als u een aangepaste opdrachtregelargumentenreeks wilt opgeven die moet worden gebruikt bij het aanroepen van het compilatieproces, stelt u de tekenreeks in de CompilerOptions eigenschap in.

Als een Win32-beveiligingstoken is vereist om het compilerproces aan te roepen, geeft u het token op in de UserToken eigenschap.

Als u een Win32-resourcebestand wilt koppelen aan de gecompileerde assembly, geeft u de naam op van het Win32-resourcebestand in de Win32Resource eigenschap.

Als u een waarschuwingsniveau wilt opgeven waarop de compilatie moet worden gestopt, stelt u de WarningLevel eigenschap in op een geheel getal dat het waarschuwingsniveau aangeeft waarop de compilatie moet worden gestopt. U kunt de compiler ook zo configureren dat de compilatie wordt gestopt als er waarschuwingen worden aangetroffen door de TreatWarningsAsErrors eigenschap in te stellen op true.

In het volgende codevoorbeeld ziet u hoe u een bronbestand compileert met behulp van een CodeDom-provider die is afgeleid van de CodeDomProvider klasse.

public:
    static bool CompileCSharpCode(String^ sourceFile, String^ exeFile)
    {
        CSharpCodeProvider^ provider = gcnew CSharpCodeProvider();

        // Build the parameters for source compilation.
        CompilerParameters^ cp = gcnew 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);
            for each (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;
        }
    }
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 {sourceFile} into {cr.PathToAssembly}");
        foreach (CompilerError ce in cr.Errors)
        {
            Console.WriteLine($"  {ce.ToString()}");
            Console.WriteLine();
        }
    }
    else
    {
        Console.WriteLine($"Source {sourceFile} built into {cr.PathToAssembly} successfully.");
    }

    // Return the results of compilation.
    if (cr.Errors.Count > 0)
    {
        return false;
    }
    else
    {
        return true;
    }
}
Public Shared Function CompileCSharpCode(sourceFile As String, _
    exeFile As String) As Boolean
    Dim provider As New CSharpCodeProvider()

    ' Build the parameters for source compilation.
    Dim cp As 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.
    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)
        For Each ce As CompilerError 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

Talen met initiële ondersteuning

.NET biedt codecompilers en codegeneratoren voor de volgende talen: C#, Visual Basic, C++en JScript. CodeDOM-ondersteuning kan worden uitgebreid naar andere talen door taalspecifieke codegeneratoren en codecompilers te implementeren.

Zie ook