我試圖編譯是針對便攜式.NET庫建一些代碼,我試圖確定要裝入便攜式組件作爲MetadataReference
對象的正確方法。在Roslyn中加載便攜式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.Runtime, 版本= 4.0.0.0,文化=中性公鑰= b03f5f7f11d50a3a」的參考。
我相信這是因爲運行該代碼的解決方案是一個4.6組件,所以typeof(object)
所指向的4.6 System.dll中。
所以我的問題是,什麼是指定便攜式組件爲MetadataReference
實例使用了羅斯林編譯對象的正確方法是什麼?
我只希望編譯引用可移植的庫,我更多地尋找一種方法來確保我知道這些可移植庫的正確位置。使用%PROGRAMFILES(X86)%或%PROGRAMFILES%是否安全,取決於我是否在x64/x86上運行?或者它可能位於不同的目錄中,具體取決於用戶如何安裝Visual Studio? –
使用'Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),而不是依賴於環境變量,但在其他方面相對於程序文件的路徑是相當不可能改變。該文件夾不依賴於VS安裝路徑(並且即使沒有安裝VS也可能存在)。 –
唯一「真正」做到這一點的方法是調用ResolveAssemblyReferences MSBuild任務,但這是那些如果你知道這個問題的轉折點,你不會問這個問題。 :-) –