Udostępnij za pośrednictwem


Generowanie i kompilowanie kodu źródłowego z wykresu CodeDOM

System.CodeDom.Compiler Przestrzeń nazw udostępnia interfejsy do generowania kodu źródłowego na podstawie grafów obiektów CodeDOM i zarządzania kompilacją przy użyciu obsługiwanych kompilatorów. Dostawca kodu może utworzyć kod źródłowy w określonym języku programowania zgodnie z grafem CodeDOM. Klasa pochodząca z CodeDomProvider klasy może zwykle udostępniać metody generowania i kompilowania kodu dla języka obsługiwanego przez dostawcę.

Generowanie kodu źródłowego przy użyciu dostawcy kodu CodeDOM

Aby wygenerować kod źródłowy w określonym języku, potrzebny jest graf CodeDOM reprezentujący strukturę kodu źródłowego do wygenerowania.

W poniższym przykładzie pokazano, jak utworzyć wystąpienie klasy CSharpCodeProvider:

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

Wykres generowania kodu jest zwykle zawarty w elemecie CodeCompileUnit. Aby wygenerować kod dla elementu CodeCompileUnit zawierającego graf CodeDOM, wywołaj GenerateCodeFromCompileUnit metodę dostawcy kodu. Ta metoda ma parametr , TextWriter którego używa do generowania kodu źródłowego, dlatego czasami konieczne jest utworzenie TextWriter obiektu , do którego można zapisać. W poniższym przykładzie pokazano generowanie kodu na podstawie CodeCompileUnit elementu i zapisywanie wygenerowanego kodu źródłowego do pliku o nazwie 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

Kompilowanie zestawów przy użyciu dostawcy kodu CodeDOM

Wywoływanie kompilacji

Aby skompilować zestaw przy użyciu dostawcy CodeDom, musisz mieć kod źródłowy do skompilowania w języku, dla którego masz kompilator, lub graf CodeDOM, z którego można skompilować kod źródłowy.

Jeśli kompilujesz z grafu CodeDOM, przekaż CodeCompileUnit go do CompileAssemblyFromDom metody dostawcy kodu. Jeśli masz plik kodu źródłowego w języku zrozumiałym przez kompilator, przekaż nazwę pliku zawierającego kod źródłowy do CompileAssemblyFromFile metody dostawcy CodeDom. Można również przekazać ciąg zawierający kod źródłowy w języku, który kompilator rozumie do CompileAssemblyFromSource metody dostawcy CodeDom.

Konfigurowanie parametrów kompilacji

Wszystkie standardowe metody wywoływania kompilacji dostawcy CodeDom mają parametr typu CompilerParameters , który wskazuje opcje do użycia do kompilacji.

Nazwę pliku dla zestawu wyjściowego można określić we OutputAssembly właściwości CompilerParameters. W przeciwnym razie zostanie użyta domyślna nazwa pliku wyjściowego.

Domyślnie nowy CompilerParameters element jest inicjowany z właściwością GenerateExecutable ustawioną na falsewartość . Jeśli kompilujesz program wykonywalny, musisz ustawić GenerateExecutable właściwość na true. GenerateExecutable Gdy parametr ma wartość false, kompilator wygeneruje bibliotekę klas.

Jeśli kompilujesz plik wykonywalny z grafu CodeDOM, CodeEntryPointMethod element musi być zdefiniowany na grafie. Jeśli istnieje wiele punktów wejścia kodu, może być konieczne ustawienie MainClass właściwości na CompilerParameters nazwę klasy, która definiuje punkt wejścia do użycia.

Aby uwzględnić informacje debugowania w wygenerowanym pliku wykonywalnym, ustaw IncludeDebugInformation właściwość na truewartość .

Jeśli projekt odwołuje się do jakichkolwiek zestawów, należy określić nazwy zestawów jako elementy w StringCollection postaci ReferencedAssemblies właściwości używanej CompilerParameters podczas wywoływania kompilacji.

Zestaw zapisywany w pamięci, a nie dysk, można skompilować, ustawiając GenerateInMemory właściwość na truewartość . Gdy zestaw jest generowany w pamięci, kod może uzyskać odwołanie do wygenerowanego zestawu z CompiledAssembly właściwości .CompilerResults Jeśli zestaw jest zapisywany na dysku, możesz uzyskać ścieżkę do wygenerowanego zestawu z PathToAssembly właściwości .CompilerResults

Aby określić niestandardowy ciąg argumentów wiersza polecenia do użycia podczas wywoływania procesu kompilacji, ustaw ciąg we CompilerOptions właściwości .

Jeśli token zabezpieczający Win32 jest wymagany do wywołania procesu kompilatora, określ token we UserToken właściwości .

Aby połączyć plik zasobu Win32 ze skompilowanym zestawem, określ nazwę pliku zasobu Win32 we Win32Resource właściwości .

Aby określić poziom ostrzeżenia, na którym ma być wstrzymana kompilacja, ustaw WarningLevel właściwość na liczbę całkowitą reprezentującą poziom ostrzeżenia, na którym ma być wstrzymana kompilacja. Kompilator można również skonfigurować tak, aby zatrzymał kompilację, jeśli napotkano ostrzeżenia, ustawiając TreatWarningsAsErrors właściwość na true.

W poniższym przykładzie kodu pokazano kompilowanie pliku źródłowego przy użyciu dostawcy CodeDom pochodzącego CodeDomProvider z klasy.

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 {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;
    }
}
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

Języki z początkową obsługą

Platforma .NET udostępnia kompilatory kodu i generatory kodu dla następujących języków: C#, Visual Basic, C++i JScript. Obsługę codeDOM można rozszerzyć na inne języki, implementując generatory kodu specyficzne dla języka i kompilatory kodu.

Zobacz też