Question

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);
        }
    }
Was it helpful?

Solution

you can use the newly released http://msdn.microsoft.com/en-us/roslyn

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top