CodeDOM グラフからソース コードを生成およびコンパイルする

System.CodeDom.Compiler 名前空間は、CodeDOM オブジェクト グラフからソース コードを生成し、サポートされているコンパイラでコンパイルを管理するためのインターフェイスを提供します。 コード プロバイダーは、CodeDOM グラフに基づいて、特定のプログラミング言語でソース コードを生成できます。 CodeDomProvider から派生したクラスは、通常、プロバイダーが対応している言語のコードを生成し、コンパイルするためのメソッドを提供します。

CodeDOM コード プロバイダーを使用してソース コードを生成する

特定の言語でソース コードを生成するには、生成するソース コードの構造を表す CodeDOM グラフが必要です。

CSharpCodeProvider のインスタンスを作成する方法の例を次に示します。

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

コード生成のグラフは通常、CodeCompileUnit に含まれます。 CodeDOM グラフが含まれる CodeCompileUnit のコードを生成するには、コード プロバイダーの 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 グラフからコンパイルする場合、コード プロバイダーの CompileAssemblyFromDom メソッドにグラフを含む CodeCompileUnit を渡します。 コンパイラが理解できる言語のソース コード ファイルがある場合、CodeDOM プロバイダーの CompileAssemblyFromFile メソッドにソース コードを含むファイルの名前を渡します。 コンパイラが理解できる言語のソース コードを含む文字列を CodeDOM プロバイダーの CompileAssemblyFromSource メソッドに渡すこともできます。

コンパイル パラメーターを構成する

CodeDOM プロバイダーの標準的なコンパイル呼び出しメソッドにはすべて、型 CompilerParameters のパラメーターがあります。これはコンパイルに使用するオプションを示します。

CompilerParametersOutputAssembly プロパティに出力アセンブリのファイル名を指定できます。 指定しない場合、既定の出力ファイル名が使用されます。

既定では、新規の CompilerParameters は、GenerateExecutable プロパティを false に設定して初期化されます。 実行可能プログラムをコンパイルする場合、GenerateExecutable プロパティを true に設定する必要があります。 GenerateExecutablefalse に設定すると、コンパイラによってクラス ライブラリが生成されます。

CodeDOM グラフから実行可能ファイルをコンパイルする場合、グラフに CodeEntryPointMethod を定義する必要があります。 コードのエントリ ポイントが複数存在するとき、場合によっては、使用するエントリ ポイントを定義するクラスの名前に MainClassCompilerParameters プロパティを設定する必要があります。

生成された実行可能ファイルにデバッグ情報を追加するには、IncludeDebugInformation プロパティを true に設定します。

プロジェクトでアセンブリを参照する場合は、コンパイルを呼び出すときに使用する CompilerParametersReferencedAssemblies プロパティと同様に StringCollection 内に項目として該当するアセンブリ名を指定する必要があります。

GenerateInMemory プロパティを true に設定することで、ディスクではなくメモリに書き込まれるアセンブリをコンパイルできます。 アセンブリをメモリに生成すると、CompilerResultsCompiledAssembly プロパティから生成されたアセンブリの参照がコードに与えられることがあります。 アセンブリをディスクに書き込む場合、CompilerResultsPathToAssembly プロパティから生成されたアセンブリのパスを取得できます。

コンパイル プロセスを呼び出すときに使用するカスタムのコマンドライン引数を指定するには、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 {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

初期サポートの言語

.NET には次の言語のためのコード コンパイラとコード ジェネレーターが用意されています: C#、Visual Basic、C++、JScript。 CodeDOM のサポートは、言語固有のコード ジェネレーターとコード コンパイラを実装することで、他の言語に拡張できます。

関連項目