Generowanie i kompilowanie kodu źródłowego z wykresu CodeDOM
System.CodeDom.Compiler Przestrzeń nazw udostępnia interfejsy do generowania kodu źródłowego na podstawie grafów obiektów CodeDOM i zarządzania kompilacją przy użyciu obsługiwanych kompilatorów. Dostawca kodu może utworzyć kod źródłowy w określonym języku programowania zgodnie z grafem CodeDOM. Klasa pochodząca z CodeDomProvider klasy może zwykle udostępniać metody generowania i kompilowania kodu dla języka obsługiwanego przez dostawcę.
Generowanie kodu źródłowego przy użyciu dostawcy kodu CodeDOM
Aby wygenerować kod źródłowy w określonym języku, potrzebny jest graf CodeDOM reprezentujący strukturę kodu źródłowego do wygenerowania.
W poniższym przykładzie pokazano, jak utworzyć wystąpienie klasy CSharpCodeProvider:
CSharpCodeProvider^ provider = gcnew CSharpCodeProvider();
CSharpCodeProvider provider = new CSharpCodeProvider();
Dim provider As New CSharpCodeProvider()
Wykres generowania kodu jest zwykle zawarty w elemecie CodeCompileUnit. Aby wygenerować kod dla elementu CodeCompileUnit
zawierającego graf CodeDOM, wywołaj GenerateCodeFromCompileUnit metodę dostawcy kodu. Ta metoda ma parametr , TextWriter którego używa do generowania kodu źródłowego, dlatego czasami konieczne jest utworzenie TextWriter
obiektu , do którego można zapisać. W poniższym przykładzie pokazano generowanie kodu na podstawie CodeCompileUnit
elementu i zapisywanie wygenerowanego kodu źródłowego do pliku o nazwie 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
Kompilowanie zestawów przy użyciu dostawcy kodu CodeDOM
Wywoływanie kompilacji
Aby skompilować zestaw przy użyciu dostawcy CodeDom, musisz mieć kod źródłowy do skompilowania w języku, dla którego masz kompilator, lub graf CodeDOM, z którego można skompilować kod źródłowy.
Jeśli kompilujesz z grafu CodeDOM, przekaż CodeCompileUnit go do CompileAssemblyFromDom metody dostawcy kodu. Jeśli masz plik kodu źródłowego w języku zrozumiałym przez kompilator, przekaż nazwę pliku zawierającego kod źródłowy do CompileAssemblyFromFile metody dostawcy CodeDom. Można również przekazać ciąg zawierający kod źródłowy w języku, który kompilator rozumie do CompileAssemblyFromSource metody dostawcy CodeDom.
Konfigurowanie parametrów kompilacji
Wszystkie standardowe metody wywoływania kompilacji dostawcy CodeDom mają parametr typu CompilerParameters , który wskazuje opcje do użycia do kompilacji.
Nazwę pliku dla zestawu wyjściowego można określić we OutputAssembly właściwości CompilerParameters
. W przeciwnym razie zostanie użyta domyślna nazwa pliku wyjściowego.
Domyślnie nowy CompilerParameters
element jest inicjowany z właściwością GenerateExecutable ustawioną na false
wartość . Jeśli kompilujesz program wykonywalny, musisz ustawić GenerateExecutable
właściwość na true
. GenerateExecutable
Gdy parametr ma wartość false
, kompilator wygeneruje bibliotekę klas.
Jeśli kompilujesz plik wykonywalny z grafu CodeDOM, CodeEntryPointMethod element musi być zdefiniowany na grafie. Jeśli istnieje wiele punktów wejścia kodu, może być konieczne ustawienie MainClass właściwości na CompilerParameters
nazwę klasy, która definiuje punkt wejścia do użycia.
Aby uwzględnić informacje debugowania w wygenerowanym pliku wykonywalnym, ustaw IncludeDebugInformation właściwość na true
wartość .
Jeśli projekt odwołuje się do jakichkolwiek zestawów, należy określić nazwy zestawów jako elementy w StringCollection postaci ReferencedAssemblies właściwości używanej CompilerParameters
podczas wywoływania kompilacji.
Zestaw zapisywany w pamięci, a nie dysk, można skompilować, ustawiając GenerateInMemory właściwość na true
wartość . Gdy zestaw jest generowany w pamięci, kod może uzyskać odwołanie do wygenerowanego zestawu z CompiledAssembly właściwości .CompilerResults Jeśli zestaw jest zapisywany na dysku, możesz uzyskać ścieżkę do wygenerowanego zestawu z PathToAssembly właściwości .CompilerResults
Aby określić niestandardowy ciąg argumentów wiersza polecenia do użycia podczas wywoływania procesu kompilacji, ustaw ciąg we CompilerOptions właściwości .
Jeśli token zabezpieczający Win32 jest wymagany do wywołania procesu kompilatora, określ token we UserToken właściwości .
Aby połączyć plik zasobu Win32 ze skompilowanym zestawem, określ nazwę pliku zasobu Win32 we Win32Resource właściwości .
Aby określić poziom ostrzeżenia, na którym ma być wstrzymana kompilacja, ustaw WarningLevel właściwość na liczbę całkowitą reprezentującą poziom ostrzeżenia, na którym ma być wstrzymana kompilacja. Kompilator można również skonfigurować tak, aby zatrzymał kompilację, jeśli napotkano ostrzeżenia, ustawiając TreatWarningsAsErrors właściwość na true
.
W poniższym przykładzie kodu pokazano kompilowanie pliku źródłowego przy użyciu dostawcy CodeDom pochodzącego CodeDomProvider z klasy.
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
Języki z początkową obsługą
Platforma .NET udostępnia kompilatory kodu i generatory kodu dla następujących języków: C#, Visual Basic, C++i JScript. Obsługę codeDOM można rozszerzyć na inne języki, implementując generatory kodu specyficzne dla języka i kompilatory kodu.