Gerando o código-fonte e compilar um programa a partir de um gráfico CodeDOM
O System.CodeDom.Compiler namespace fornece interfaces para gerar código de origem de gráficos de objeto do CodeDOM e gerenciar a compilação com compiladores com suporte. Um provedor de código pode produzir código-fonte em uma determinada linguagem de programação de acordo com a um gráfico de CodeDOM. Uma classe que deriva de CodeDomProvider geralmente pode fornecer métodos para gerar e compilar o código para o idioma do provedor oferece suporte.
Usando um provedor de código CodeDOM para gerar o código-fonte
Para gerar o código-fonte em um determinado idioma, você precisa de um gráfico de CodeDOM representa a estrutura de código-fonte para gerar.
O exemplo a seguir demonstram como criar uma instância de um CSharpCodeProvider:
Dim provider As New CSharpCodeProvider()
CSharpCodeProvider provider = new CSharpCodeProvider();
CSharpCodeProvider^ provider = gcnew CSharpCodeProvider();
Normalmente, o gráfico para a geração de código está contido em um CodeCompileUnit. Para gerar código para um CodeCompileUnit que contém um gráfico CodeDOM, chame o GenerateCodeFromCompileUnit o método do provedor de código. Este método tem um parâmetro para um TextWriter que ele usa para gerar o código-fonte, às vezes, é necessário primeiro criar um TextWriter que podem ser gravadas. O exemplo a seguir demonstra o código de geração de um CodeCompileUnit e escrever o código-fonte gerado em um arquivo denominado 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;
}
Usando um provedor de código CodeDOM compilar assemblies
Invocar a compilação
Para compilar um assembly usando um provedor de CodeDom, você deve ter um código de origem para compilar em um idioma para o qual você tem um compilador ou um CodeDOM gráfico essa fonte de código seja compilado pode ser gerado a partir.
Se você está compilando a partir de um gráfico CodeDOM, passar o CodeCompileUnit que contém o gráfico para o CompileAssemblyFromDom o método do provedor de código. Se você tiver um arquivo de código-fonte em um idioma que o compilador compreende, passe o nome do arquivo que contém o código-fonte para o CompileAssemblyFromFile o método do provedor de CodeDom. Você também pode passar uma seqüência de caracteres que contém o código-fonte em um idioma que o compilador compreende para o CompileAssemblyFromSource o método do provedor de CodeDom.
Configurando parâmetros de compilação
Todos os métodos padrão de invocar a compilação de um provedor de CodeDom têm um parâmetro do tipo CompilerParameters que indica as opções para usar para compilação.
Você pode especificar um nome de arquivo do assembly de saída na OutputAssembly propriedade da CompilerParameters. Caso contrário, será usado um nome de arquivo de saída padrão.
Por padrão, uma nova CompilerParameters é inicializada com seu GenerateExecutable propriedade definida como false. Se você está compilando um programa executável, você deve definir o GenerateExecutable propriedade para true. Quando o GenerateExecutable for definido como false, o compilador irá gerar uma biblioteca de classe.
Se você está compilando um executável de um gráfico CodeDOM, um CodeEntryPointMethod deve ser definido no gráfico. Se houver vários pontos de entrada de código, talvez seja necessário definir o MainClass propriedade da CompilerParameters com o nome da classe que define o ponto de entrada para usar.
Para incluir informações de depuração em um executável gerado, defina a IncludeDebugInformation propriedade para true.
Se o seu projeto faz referência a todos os assemblies, você deve especificar os nomes de assembly como itens em um StringCollection como o ReferencedAssemblies propriedade da CompilerParameters você usar ao chamar a compilação.
Você pode compilar um assembly que é gravado para a memória, em vez de disco, definindo a GenerateInMemory propriedade para true. Quando um assembly é gerado na memória, seu código pode obter uma referência ao assembly gerado a partir de CompiledAssembly propriedade de um CompilerResults. Se um assembly é gravado para disco, você pode obter o caminho para o assembly gerado a partir do PathToAssembly propriedade de um CompilerResults.
Para especificar uma seqüência de argumentos de linha de comando personalizado a ser usado ao invocar o processo de compilação, defina a seqüência de caracteres CompilerOptions propriedade.
Se um token de segurança do Win32 é necessária para chamar o processo de compilador, especifique o token na UserToken propriedade.
Para vincular um arquivo de recurso do Win32 no assembly compilado, especifique o nome do arquivo de recurso Win32 na Win32Resource propriedade.
Para especificar um nível de aviso interromper a compilação, defina a WarningLevel a propriedade para um inteiro que representa o nível de aviso interromper a compilação. Você também pode configurar o compilador para interromper a compilação se avisos são encontrados, definindo a TreatWarningsAsErrors propriedade para true.
O exemplo de código a seguir demonstra a compilar um arquivo de origem usando um provedor de CodeDom derivado de CodeDomProvider classe.
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;
}
}
Idiomas com suporte a inicial
A.NET Framework fornece os compiladores de código e geradores de código para os seguintes idiomas: C#, Visual Basic, C++, j# e JScript. Suporte de codeDOM pode ser estendido para outros idiomas, Implementando os geradores de código específico de linguagem e compiladores de código.