c # получение внутренней ошибки в оценщике выражений при программной компиляции кода с Roslyn - PullRequest
0 голосов
/ 28 октября 2018

Я создал консольный проект, который компилирует код при сборке на основе нескольких действительно простых шаблонов, которые у меня есть. Шаблоны просто устанавливают классы, которые наследуются от базовых классов в другом проекте. Я могу запустить код и построчно пройтись по базовым классам, но когда я пытаюсь увидеть значение свойства, я получаю Internal error in the expression evaluator. Я попытался настроить консольный проект для компиляции всего с конфигурациями отладки:

CSharpCompilationOptions DefaultCompilationOptions =
    new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
        .WithOverflowChecks(true)
        .WithOptimizationLevel(OptimizationLevel.Debug)
        .WithOutputKind(OutputKind.DynamicallyLinkedLibrary)
        .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

CSharpCompilation compilation = CSharpCompilation.Create(
    name,
    syntaxTrees: syntaxTrees,
    references: GetMetaDataReferences(context, moduleBinPath),
    options: DefaultCompilationOptions);

try
{
    var ms = new MemoryStream();
    var pdbStream = new MemoryStream();
    var docStream = new MemoryStream();

    var result = compilation.Emit(ms, pdbStream, docStream);
    if (!result.Success)
    {
        IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
            diagnostic.IsWarningAsError ||
            diagnostic.Severity == DiagnosticSeverity.Error);

        foreach (Diagnostic diagnostic in failures)
        {
            Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
        }
    }
    else
    {
        CreateFile($"{moduleBinPath}\\{name}.dll", ms);
        CreateFile($"{moduleBinPath}\\{name}.pdb", pdbStream);
        CreateFile($"{moduleBinPath}\\{name}.xml", docStream);
    }

    ms.Dispose();
    pdbStream.Dispose();
    docStream.Dispose();
}
catch (Exception ex)
{
    Console.Error.WriteLine("Could not compile assembly!!");
    Console.Error.WriteLine(ex.ToString());
}

Затем я загружаю DLL при запуске:

string scriptPath = $"{moduleBinPath}\\{moduleAssembly}.Scripts.dll";
if (File.Exists(scriptPath))
{
    Assembly.LoadFile(scriptPath)
    AssemblyLoadContext.Default.Resolving += (loadContext, name) =>
    {
        if (!name.Name.Equals($"{moduleAssembly}.Scripts")) return null;
        return loadContext.LoadFromAssemblyPath(scriptPath);
    };
}

Я вижу, что символы также загружаются в окне модулей. Что еще мне нужно сделать, чтобы отладка работала нормально?

1 Ответ

0 голосов
/ 29 октября 2018

На самом деле я понял, что самая большая проблема была в том, что я использовал Assembly.LoadFile вместо AssemblyLoadContext.Default.LoadFromAssemblyPath.Последнее намного лучше при загрузке зависимых сборок плагина.

Проведя немного больше исследований, я наткнулся на эту статью , в которой рассказывается о ненадежности Assembly.LoadFile.Трудно сказать, в чем именно заключалась проблема, но я предполагаю, что, возможно, были некоторые несоответствия версий сборки, из-за которых оценщик выражений не работал должным образом.

...