Microsoft.CodeDom.Providers.DotNetCompilerPlatform

时间:2019-12-13 17:51:17

标签: c# .net .net-core

我有一个应用程序,可以执行一些动态代码生成和编译,并且可以与System.CodeDom和Microsoft.CSharp一起正常运行。我将其移植到.net Core 3.1,因此已升级为使用Microsoft.CodeDom.Providers.DotNetCompilerPlatform。但是,我遇到了可能相关的问题。首先是Visual Studio在“引用”的“包”部分中显示以下消息:

  

软件包'Microsoft.CodeDom.Providers.DotNetCompilerPlatform 2.0.1'是   使用'.NETFramework,Version = v4.6.1恢复,   .NETFramework,Version = v4.6.2,.NETFramework,Version = v4.7,   .NETFramework,Version = v4.7.1,.NETFramework,Version = v4.7.2,   .NETFramework,Version = v4.8',而不是项目目标框架   '.NETCoreApp,Version = v3.1'。该软件包可能不完全兼容   与您的项目。

第二(可能与此相关),当应用程序点击以下行时:

CSharpCodeProvider codeProvider = new CSharpCodeProvider();

然后引发以下异常:

  

“ Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CompilationSettingsHelper”的类型初始值设定项引发了异常。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

希望这对其他尝试解决同一问题的人有所帮助,这就是我最后使用Microsoft.CodeAnalysis.CSharp包的原因:

Assembly assembly = null;
string[] sourceStringArray = null;// set this to hold the arrary of source strings
List<SyntaxTree> syntaxTreeList = new List<SyntaxTree>();
foreach (string sourceString in sourceStringArray)
{
    SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceString);
    syntaxTreeList.Add(syntaxTree);
}

string assemblyName = Path.GetRandomFileName();
AppDomain currentDomain = AppDomain.CurrentDomain;
List<MetadataReference> metadataReferenceList = new List<MetadataReference>();
Assembly[] assemblyArray = currentDomain.GetAssemblies();
foreach (Assembly domainAssembly in assemblyArray)
{
    try
    {
        AssemblyMetadata assemblyMetadata = AssemblyMetadata.CreateFromFile(domainAssembly.Location);
        MetadataReference metadataReference = assemblyMetadata.GetReference();
        metadataReferenceList.Add(metadataReference);
    }
    catch (Exception e)
    {
        Log.DebugFormat("failed to get MetadataReference {0}", e.Message);
    }
}

CSharpCompilation compilation = CSharpCompilation.Create(
    assemblyName,
    syntaxTrees: syntaxTreeList,
    references: metadataReferenceList,
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
    EmitResult result = compilation.Emit(ms);
    if (!result.Success)
    {
        IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);
        foreach (Diagnostic diagnostic in failures)
        {
            /* Process failures */
        }
    }
    else
    {
        ms.Seek(0, SeekOrigin.Begin);
        assembly = Assembly.Load(ms.ToArray());
    }
}

我确信这不是最佳选择(欢迎提出改进建议!)。