![](/img/trans.png)
[英]Is there a way to use Microsoft.CodeDom.Providers.DotNetCompilerPlatform without a nuget package?
[英]Problem with Microsoft.CodeDom.Providers.DotNetCompilerPlatform
我有一个执行一些动态代码生成和编译的应用程序,并且与 System.CodeDom 和 Microsoft.CSharp 配合得很好。 我将其移植到 .net Core 3.1,因此已升级为使用 Microsoft.CodeDom.Providers.DotNetCompilerPlatform。 但是,我遇到了可能相关的问题。 首先是 Visual Studio 在“参考资料”的“包”部分显示以下消息:
使用“.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4”恢复包“Microsoft.CodeDom.Providers.DotNetCompilerPlatform 2.0.1” .7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' 而不是项目目标框架 '.NETCoreApp,Version=v3.1'。 此包可能与您的项目不完全兼容。
其次(这可能是相关的),当应用程序点击这条线时:
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
然后抛出以下异常:
“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CompilationSettingsHelper”的类型初始值设定项引发异常。
我将不胜感激任何帮助!
希望这可以帮助其他人尝试解决同样的问题,这是我最终使用 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());
}
}
我确信这不是最优的(并且欢迎提出改进建议。)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.