Share via


從 CodeDOM 物件 Graph 產生原始程式碼和編譯程式

System.CodeDom.Compiler 命名空間提供的介面可從 CodeDOM 物件 Graph 產生原始程式碼,並管理支援編譯器的編譯工作。 程式碼提供者可以根據 CodeDOM 物件 Graph,在特定程式語言中產生原始程式碼。 衍生自 CodeDomProvider 的類別通常可以為提供者支援的語言,提供產生及編譯程式碼的方法。

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

若要在特定語言中產生原始程式碼,您需要表示要產生之原始程式碼結構的 CodeDOM 物件 Graph。

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

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

用來產生程式碼的 Graph 通常包含在 CodeCompileUnit 中。 若要替包含 CodeDOM 物件 Graph 的 CodeCompileUnit 產生程式碼,請呼叫程式碼提供者的 GenerateCodeFromCompileUnit 方法。 這個方法有一個 TextWriter 的參數,用來產生原始程式碼,因此有時需要先建立可以寫入的 TextWriter。 下列範例示範從 CodeCompileUnit 產生程式碼,並將產生的原始程式碼寫入名為 HelloWorld.cs 的檔案。

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

使用 CodeDOM 程式碼提供者編譯組件

叫用編譯

若要使用 CodeDom 提供者編譯組件,您必須具有要編譯之原始程式碼的語言編譯器,或是可以藉此產生要編譯之原始程式碼的 CodeDOM 物件 Graph。

如果要從 CodeDOM 物件 Graph 編譯,請將包含 Graph 的 CodeCompileUnit 傳遞給程式碼提供者的 CompileAssemblyFromDom 方法。 如果您的原始程式碼檔案使用編譯器了解的語言,請將包含原始程式碼的檔案名稱傳遞給 CodeDom 提供者的 CompileAssemblyFromFile 方法。 您也可以將包含原始程式碼的字串 (使用編譯器了解的語言) 傳遞給 CodeDom 提供者的 CompileAssemblyFromSource 方法。

設定編譯參數

CodeDom 提供者的所有標準編譯叫用方法,都有型別為 CompilerParameters 的參數,表示要用於編譯的選項。

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

依預設,新的 CompilerParameters 在初始化時,其 GenerateExecutable 屬性會設定為 false。 如果您正在編譯可執行程式,必須將 GenerateExecutable 屬性設定為 trueGenerateExecutable 設定為 false 時,編譯器將會產生類別庫。

如果在 CodeDOM 物件 Graph 中編譯可執行檔,必須在 Graph 中定義 CodeEntryPointMethod。 如果有多個程式碼進入點,可能需要先確定是由哪個類別定義要使用的進入點,然後將 CompilerParametersMainClass 屬性設定為該類別名稱。

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

如果專案參考任何組件,您必須將組件名稱指定為 StringCollection 中的項目,如同叫用編譯時使用的 CompilerParametersReferencedAssemblies 屬性。

GenerateInMemory 屬性設為 true,可以編譯寫入記憶體而不是磁碟的組件。 在記憶體中產生組件時,可取得由 CompilerResultsCompiledAssembly 屬性所產生組件的參考。 如果是將組件寫入磁碟,您可以從 CompilerResultsPathToAssembly 屬性取得產生的組件所在路徑。

若要指定叫用編譯程序時要用的自定指令行引數字串,請在 CompilerOptions 屬性中設定字串。

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

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

若要指定暫停編譯的警告層級,請將 WarningLevel 屬性設為代表暫停編譯之警告層級的整數。 將 TreatWarningsAsErrors 屬性設定為 true,也可以將編譯器設定為遭遇警告時即暫停編譯。

下列程式碼範例將示範如何使用衍生自 CodeDomProvider 類別的 CodeDom 提供者來編譯原始程式檔。

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

初期支援的語言

.NET Framework 提供下列語言的程式碼編譯器和程式碼產生器:C#、Visual Basic、C++、J# 和 JScript。 CodeDOM 支援可藉由實作語言專屬的程式碼產生器和程式碼編譯器擴充至其他語言。

請參閱

參考

CodeDOM 快速參考

System.CodeDom

System.CodeDom.Compiler

其他資源

動態原始程式碼的產生和編譯