Introduction
CSCompiler is a simple application for compiling single file C# source code.
It was written in C#. Of course I didn't wrote a whole C# compiler. Instead
I've used interfaces provided by the .NET platform.
What you have to do in order to have a C# compiler :
- Create an instance of
CSharpCodeProvider
(VBCodeProvider
for Visual Basic)
- Obtain interface for
ICodeCompiler
- Provide
CompilerParameters
for compiler options
- Compile source code using
CompileAssemblyFromSource
method of ICodeCompiler
interface
- Process
CompilerResults
- Execute generated application if there were no errors
That's it.
This scenario uses code provided as a string, but you can also use source files.
You can also generate an assembly in memory , but generating binary a application
is better for viewing 'physical' result of a compiler.
This simple application forces you to type in a main class of the application (it is not so tricky as it could be :( ).
The assembly references of CSCompiler application should be enough for most of the
simplest applications, but if not you must add more assembly references to
CompilerParamters
to work fine.
The "Compile and Execute" button code look like :
private void button1_Click(object sender, System.EventArgs e)
{
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler compiler = codeProvider.CreateCompiler();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
if (appName.Text == "")
{
System.Windows.Forms.MessageBox.Show(this,
"Application name cannot be empty");
return ;
}
parameters.OutputAssembly = appName.Text.ToString();
if (mainClass.Text.ToString() == "")
{
System.Windows.Forms.MessageBox.Show(this,
"Main Class Name cannot be empty");
return ;
}
parameters.MainClass = mainClass.Text.ToString();
parameters.IncludeDebugInformation = includeDebug.Checked;
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
parameters.ReferencedAssemblies.Add(asm.Location);
}
String code = textBox1.Text.ToString();
CompilerResults results = compiler.CompileAssemblyFromSource(parameters,
code);
if (results.Errors.Count > 0)
{
string errors = "Compilation failed:\n";
foreach (CompilerError err in results.Errors)
{
errors += err.ToString() + "\n";
}
System.Windows.Forms.MessageBox.Show(this, errors,
"There were compilation errors");
}
else
{
#region Executing generated executable
try
{
if (!System.IO.File.Exists(appName.Text.ToString()))
{
MessageBox.Show(String.Format("Can't find {0}", appName),
"Can't execute.", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
ProcessStartInfo pInfo = new ProcessStartInfo(appName.Text.ToString());
Process.Start(pInfo);
}
catch (Exception ex)
{
MessageBox.Show(String.Format("Error while executing {0}",
appName) + ex.ToString(), "Can't execute.",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
#endregion
}
}
If you want to know more about CodeProvider interfaces look at NAnt project at sourceforge.
Credits: