Reputation: 117
I'm using the CodeDom to allow custom scripts (C#) to be run in an application I'm creating. While writing the script I would like to be able to check for compile errors. The code gets added to and compiled into memory at a much later time and run so i don't want the assembly compiled while writing the script to remain in memory.
What's the best way to achieve this?
Is it possible to remove the assembly from memory after compiling?
private void Item_Click(object sender, EventArgs e)
{
List<string> assemblyNames = new List<string> { };
List<string> code = new List<string> { };
foreach (string str in GetCompileParameters())
if (!assemblyNames.Contains(str))
assemblyNames.Add(str);
code.AddRange(GetScriptCode());
CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
CompilerParameters mCompileParams = new CompilerParameters(assemblyNames.ToArray());
mCompileParams.GenerateInMemory = true;
mCompileParams.CompilerOptions = "/target:library /optimize";
CompilerResults results = provider.CompileAssemblyFromSource(mCompileParams, code.ToArray());
if (results.Errors.HasErrors)
{
string error = "The following compile error occured:\r\n";
foreach (CompilerError err in results.Errors)
error += "File: " + err.FileName + "; Line (" + err.Line + ") - " + err.ErrorText + "\n";
MessageBox.Show(error);
return;
}
MessageBox.Show("No errors found");
//Need to Remove assembly here
}
Update:
Thank you Keith.
For anyone interested this is the new code i'm using with Roslyn
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
...
private void Item_Click(object sender, EventArgs e)
{
List<string> assemblyNames = new List<string> { };
foreach (string str in GetCompileParameters())
if (!assemblyNames.Contains(str))
assemblyNames.Add(str);
SyntaxTree tree = SyntaxTree.ParseCompilationUnit(mScenario.GetScriptCode("ScriptName"));
Compilation com = Compilation.Create("Script");
com = com.AddReferences(new AssemblyFileReference(typeof(Object).Assembly.Location)); // Add reference mscorlib.dll
com = com.AddReferences(new AssemblyFileReference(typeof(System.Linq.Enumerable).Assembly.Location)); // Add reference System.Core.dll
com = com.AddReferences(new AssemblyFileReference(typeof(System.Net.Cookie).Assembly.Location)); // Add reference System.dll
foreach (string str in assemblyNames)
com = com.AddReferences(new AssemblyFileReference(str)); // Add additional references
com = com.AddSyntaxTrees(tree);
Diagnostic[] dg = com.GetDiagnostics().ToArray();
if (dg.Length > 0)
{
string error = "The following compile error occured:\r\n";
foreach (Diagnostic d in dg)
error += "Info: " + d.Info + "\n";
MessageBox.Show(error, "Compile Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
} else {
MessageBox.Show("No errors found.", "Code Compiler", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
Upvotes: 3
Views: 3797
Reputation: 11615
For an example of how to do this with the Roslyn CTP, take a look at http://www.dotnetexpertguide.com/2011/10/c-sharp-syntax-checker-aspnet-roslyn.html
Upvotes: 1
Reputation: 44308
you can use the newly released http://msdn.microsoft.com/en-us/roslyn
Upvotes: 2