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

更新 : 2007 年 11 月

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

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

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

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

Dim provider As New CSharpCodeProvider()
CSharpCodeProvider provider = new 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 CSharpCodeProvider = New CSharpCodeProvider()

    ' Build the output file name.
    Dim sourceFile As String
    If provider.FileExtension.StartsWith(".")
        sourceFile = "HelloWorld" + provider.FileExtension
    Else
        sourceFile = "HelloWorld." + provider.FileExtension
    End If

    ' Create a TextWriter to a StreamWriter to an output file.
    Dim tw As New IndentedTextWriter( _
        New StreamWriter(sourceFile, False), "    ")

    ' Generate source code using the code provider.
    provider.GenerateCodeFromCompileUnit(compileunit, tw, _
        New CodeGeneratorOptions())

    ' Close the output file.
    tw.Close()
        
    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.
    IndentedTextWriter tw = new IndentedTextWriter(
            new StreamWriter(sourceFile, false), "    ");
            
    // Generate source code using the code provider.
    provider.GenerateCodeFromCompileUnit(compileunit, tw, 
            new CodeGeneratorOptions());

    // Close the output file.
    tw.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 CSharpCodeProvider = New CSharpCodeProvider()
          
    ' Build the parameters for source compilation.
    Dim cp As New CompilerParameters()
         
    ' Add an assembly reference.
    cp.ReferencedAssemblies.Add("System.dll")

    ' Save the assembly as a physical file.
    cp.GenerateInMemory = False

    ' Generate an executable instead of a class library.
    cp.GenerateExecutable = True
          
    ' Set the assembly file name to generate.
    cp.OutputAssembly = exeFile
        
    ' 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)
        Dim ce As System.CodeDom.Compiler.CompilerError
        For Each ce 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;
    }
}

既定でサポートされる言語

.NET Framework には、C#、Visual Basic、C++、J#、および JScript の各言語に対応したコード コンパイラとコード ジェネレータが用意されています。CodeDOM に、言語固有のコード ジェネレータおよびコード コンパイラを実装することで、これら以外の言語もサポートできます。

参照

参照

CodeDOM クイック リファレンス

System.CodeDom

System.CodeDom.Compiler

その他の技術情報

高度な開発技術