소스 코드 생성 및 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 메서드로 전달해야 합니다. 컴파일러에서 식별하는 언어의 소스 코드 파일이 있으면 소스 코드가 들어 있는 파일 이름을 CodeDom 공급자의 CompileAssemblyFromFile 메서드에 전달합니다. 또한 컴파일러에서 식별하는 언어의 소스 코드가 들어 있는 문자열을 CodeDom 공급자의 CompileAssemblyFromSource 메서드에 전달할 수 있습니다.
컴파일 매개 변수 구성
CodeDom 공급자의 모든 표준 컴파일 호출 메서드에는 컴파일에 사용되는 옵션을 지정하는 CompilerParameters 형식의 매개 변수가 있습니다.
출력 어셈블리의 파일 이름은 CompilerParameters의 OutputAssembly 속성으로 지정할 수 있습니다. 그렇지 않을 경우 기본 출력 파일 이름이 사용됩니다.
기본적으로 새 CompilerParameters는 GenerateExecutable 속성을 false로 설정하여 초기화합니다. 실행 프로그램을 컴파일하는 경우에는 GenerateExecutable 속성을 true로 설정해야 합니다. GenerateExecutable을 false로 설정하면 컴파일러는 클래스 라이브러리를 생성합니다.
CodeDOM 그래프에서 실행 파일을 컴파일하는 경우 CodeEntryPointMethod가 그래프에 정의되어야 합니다. 코드 진입점이 여러 개인 경우 CompilerParameters의 MainClass 속성을 사용 대상 진입점을 정의하는 클래스 이름으로 설정해야 합니다.
생성되는 실행 파일에 디버그 정보를 포함시키려면 IncludeDebugInformation 속성을 true로 설정합니다.
프로젝트에서 어셈블리를 참조하는 경우 컴파일을 호출할 때 사용하는 CompilerParameters의 ReferencedAssemblies 속성과 같이 어셈블리 이름을 StringCollection의 항목으로 지정해야 합니다.
GenerateInMemory 속성을 true로 설정해서 디스크가 아니라 메모리에 기록되는 어셈블리를 컴파일할 수 있습니다. 어셈블리가 메모리에서 생성되면, 코드는 생성된 어셈블리에 대한 참조를 CompilerResults의 CompiledAssembly 속성에서 가져올 수 있습니다. 어셈블리가 디스크에 쓰여지면 생성된 어셈블리에 대한 경로를 CompilerResults의 PathToAssembly 속성에서 가져올 수 있습니다.
컴파일 프로세스를 호출할 때 사용할 사용자 지정 명령줄 인수 문자열을 지정하려면, 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 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을 확장할 수 있습니다.