我正在尝试编译一些针对可移植.Net库构建的代码,我正在尝试确定将可移植程序集作为MetadataReference
对象加载的正确方法。
例如,我可以像这样加载程序集,它可以工作:
var analyzerCode = "// Some analyzer code here";
var syntaxTree = CSharpSyntaxTree.ParseText(analyzerCode);
string assemblyName = System.IO.Path.GetRandomFileName();
MetadataReference[] references = new MetadataReference[]
{
MetadataReference.CreateFromFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Runtime.dll"),
MetadataReference.CreateFromFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Diagnostics.Debug.dll"),
MetadataReference.CreateFromFile(typeof(System.Collections.Immutable.ImmutableArray).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Microsoft.CodeAnalysis.CSharp.CSharpCompilation).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Microsoft.CodeAnalysis.Workspace).Assembly.Location)
};
CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, new[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
EmitResult result = compilation.Emit(ms);
// Check the result for errors and work with it
}
显然这不是非常便携的代码,因为我使用的文件路径可能只适用于我的机器。如果我执行以下操作:
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
我得到以下例外情况:
CS0012:类型'对象'在一个不是的程序集中定义 引用。您必须添加对程序集&System; System.Runtime的引用, Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'。
我相信这是因为运行此代码的解决方案是4.6程序集,因此typeof(object)
指向4.6 System.dll。
所以我的问题是,指定用作Roslyn编译对象的MetadataReference
实例的可移植程序集的正确方法是什么?
答案 0 :(得分:4)
如果您的编译引用了“完整”框架4.5或4.6,并且您还引用了可移植库,则还需要添加对façade程序集的引用以在它们之间进行桥接。您可以在以下网址找到它们:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades
您应该将v4.6替换为您要定位的桌面框架的任何版本。您应该遍历该目录并为您在其中看到的所有程序集添加引用。
答案 1 :(得分:1)
找到程序集的路径并指定要加载的可移植库。可能看起来像这样:
var dotNetAssemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
var references = new MetadataReference[]
{
MetadataReference.CreateFromFile(Path.Combine(dotNetAssemblyPath, "MY_PORTABLE_FILE_TO_BE_LOADED"))
};