Как проверить ошибки компиляции перед компиляцией с CodeDom - PullRequest
3 голосов
/ 20 октября 2011

Я использую CodeDom, чтобы разрешить запуск пользовательских сценариев (C #) в приложении, которое я создаю. При написании скрипта я хотел бы иметь возможность проверить наличие ошибок компиляции. Код добавляется и компилируется в память гораздо позже и запускается, поэтому я не хочу, чтобы сборка, скомпилированная во время написания скрипта, оставалась в памяти.

Какой лучший способ добиться этого?

Можно ли удалить сборку из памяти после компиляции?

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
}

Обновление:

Спасибо, Кит.

Для всех, кто интересуется, это новый код, который я использую с 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);
        }
    }

Ответы [ 2 ]

2 голосов
/ 20 октября 2011

вы можете использовать только что выпущенный http://msdn.microsoft.com/en-us/roslyn

1 голос
/ 21 октября 2011

Для примера того, как сделать это с Roslyn CTP, взгляните на http://www.dotnetexpertguide.com/2011/10/c-sharp-syntax-checker-aspnet-roslyn.html

...