語言

從 CodeDOM 圖表產生及編譯原始程式碼

System.CodeDom.Compiler 命名空間提供的介面,可從 CodeDOM 物件圖形產生原始程式碼以及使用支援的編譯器管理編譯。 程式碼提供者可根據 CodeDOM 圖表以特定的程式設計語言產生原始程式碼。 衍生自 CodeDomProvider 的類別一般會針對提供者支援的語言,提供產生及編譯程式碼的方法。

使用 CodeDOM 程式代碼提供者來產生原始程式碼

若要以特定語言產生原始程式碼,您需要能代表要產生的原始程式碼結構的 CodeDOM 圖表。

以下範例示範如何建立 CSharpCodeProvider 的執行個體:

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

產生程式碼的圖表一般是包含在 CodeCompileUnit 中。 若要產生 CodeCompileUnit 包含 CodeDOM 圖形之 的程式代碼,請呼叫 GenerateCodeFromCompileUnit 程式代碼提供者的方法。 這個方法有一個參數 TextWriter,用來產生原始程式碼,因此有時需要先建立一個可寫入的 TextWriter。 下列範例示範如何從 CodeCompileUnit 產生程序代碼,並將產生的原始程式碼寫入名為 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

使用 CodeDOM 程式碼提供者來編譯程序集

執行編譯

若要使用 CodeDom 提供者編譯組件,您必須有用於編譯的語言的原始程式碼(即您擁有編譯器的語言),或一個能生成要編譯之原始程式碼的 CodeDOM 圖表。

如要從 CodeDOM 圖表編譯,請將包含圖表的 CodeCompileUnit 傳送至程式碼提供者的 CompileAssemblyFromDom 方法。 如果您有以編譯器了解的語言撰寫的原始程式碼檔案,請將包含原始程式碼的檔案名稱傳遞給 CodeDom 提供者的 CompileAssemblyFromFile 方法。 您也可以將包含原始程式碼的字串 (此程式碼是以編譯器了解的語言撰寫),傳遞到 CodeDom 提供者的 CompileAssemblyFromSource 方法。

設定編譯參數

CodeDom 提供者的所有標準編譯叫用方法都有一個類型為 CompilerParameters 的參數,指示編譯要使用的選項。

您可以在 OutputAssembly 的 CompilerParameters 屬性中指定輸出組件的檔案名。 否則,會使用預設的輸出檔名稱。

根據預設,新的 CompilerParameters 會初始化,其 GenerateExecutable 屬性設定為 false。 如果您要編譯可執行的程式,則必須將 GenerateExecutable 屬性設定為 true。 GenerateExecutable當 設定為 false時,編譯程式將會產生類別庫。

如要從 CodeDOM 圖表編譯可執行檔,即必須在圖表中定義 CodeEntryPointMethod。 如果有多個程式代碼進入點,可能需要將 的 MainClass 屬性設定CompilerParameters為定義要使用的進入點之類別名稱。

若要在產生的可執行檔案中包含偵錯資訊,請將 IncludeDebugInformation 屬性設定為 true。

如果您的專案參考了任何元件,您必須在叫用編譯時,將元件名稱作為StringCollection的ReferencedAssemblies屬性,並將其指定為CompilerParameters中的項目。

您可以將GenerateInMemory屬性設定為true,以便將元件編譯至記憶體而不是磁碟。 當組件在記憶體中產生時,您的程式碼可從 CompiledAssembly 的 CompilerResults 屬性取得所產生組件的參考。 如果將元件寫入磁碟,您可以從 PathToAssembly 的 CompilerResults 屬性取得所產生之元件的路徑。

若要在叫用編譯處理序時指定使用的自訂命令列引數字串,請在 CompilerOptions 屬性中設定字串。

如果需要 Win32 安全性權杖才能叫用編譯器處理序,請在 UserToken 屬性中指定權杖。

若要將 Win32 資源檔連結至已編譯的組件,請在 Win32Resource 屬性中指定 Win32 資源檔的名稱。

若要指定中斷編譯的警告層級,請將 WarningLevel 屬性設為整數,表示要中斷編譯的警告層級。 您也可以將編譯器設定為遇到警告時停止編譯,這可以透過將TreatWarningsAsErrors屬性設定為true來實現。

下列程式碼範例示範使用衍生自 CodeDomProvider 類別的 CodeDom 提供者編譯來源檔案。

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

具有初始支持的語言

.NET 提供下列語言的程式代碼編譯程式和程式代碼產生器:C#、Visual Basic、C++和 JScript。 實作特定語言的程式碼產生器和程式碼編譯器,即可擴充 CodeDOM 對其他語言的支援。

另請參閱