CodeDOM グラフからのソース コードの生成およびプログラムのコンパイル

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

CodeDOM コード プロバイダーを使用したソース コードの生成

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

次に示すのは、CSharpCodeProvider のインスタンスを作成する方法のコード例です。

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

コードを生成するためのグラフは、通常、CodeCompileUnit に格納されます。 CodeDOM グラフを含む 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 グラフのいずれかが必要です。

CodeDOM グラフからコンパイルする場合は、グラフを格納している CodeCompileUnit をコード プロバイダーの CompileAssemblyFromDom メソッドに渡します。 コンパイラが認識できる言語のソース コード ファイルがある場合は、ソース コードを含むファイルの名前を、コード プロバイダーの CompileAssemblyFromFile メソッドに渡します。 コンパイラが認識できる言語のソース コードを含む文字列を、CodeDom プロバイダーの CompileAssemblyFromSource メソッドに渡すこともできます。

コンパイル パラメーターの構成

CodeDom プロバイダーの標準的なコンパイル実行メソッドはすべて、コンパイルに使用するオプションを示す CompilerParameters 型のパラメーターを使用します。

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

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

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

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

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

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

コンパイル処理を実行するときに使用するカスタム コマンド ライン引数の文字列を指定するには、CompilerOptions プロパティに文字列を設定します。

コンパイラ プロセスを起動するために Win32 セキュリティ トークンが必要な場合は、そのトークンを UserToken プロパティに指定します。

コンパイルされるアセンブリに Win32 リソース ファイルへのリンクを設定するには、Win32 リソース ファイルの名前を Win32Resource プロパティに指定します。

コンパイルを中断する警告レベルを指定するには、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

その他の技術情報

動的なソース コードの生成とコンパイル