Ben*_*son 1 .net c# macos roslyn .net-core
我正在尝试在 OSX 上的 .NET Core 中从 C# 调用 Roslyn。
public class Program
{
public static void Main()
{
var cscArgs = CSharpCommandLineParser.Default.Parse(
new[] { "/target:Library" },
Directory.GetCurrentDirectory(),
"/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.1.0/"
);
var refs = cscArgs.MetadataReferences.Select(x => MetadataReference.CreateFromFile(x.Reference, x.Properties));
foreach (var r in refs)
{
Console.WriteLine(r.FilePath);
}
var trees = new[]
{
CSharpSyntaxTree.ParseText("class Foo {}", cscArgs.ParseOptions)
};
var compilation = CSharpCompilation.Create(cscArgs.CompilationName, trees, refs, cscArgs.CompilationOptions);
using (var peStream = File.OpenWrite("test.dll"))
{
var emitResult = compilation.Emit(peStream, null, null, null, cscArgs.ManifestResources, cscArgs.EmitOptions);
foreach (var d in emitResult.Diagnostics)
{
Console.WriteLine(d);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时, (test.dll保持为空并且) WriteLines 打印出一个,MetadataReference然后是一个警告和两个编译错误:
/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.1.0/mscorlib.dll
warning CS8021: No value for RuntimeMetadataVersion found. No assembly containing System.Object was found nor was a value for RuntimeMetadataVersion specified through options.
(2,31): error CS0518: Predefined type 'System.Object' is not defined or imported
(2,31): error CS1729: 'object' does not contain a constructor that takes 0 arguments
Run Code Online (Sandbox Code Playgroud)
所以看起来Compilation没有拿起mscorlib参考。DLL 确实存在于引用的位置。
$ ls /usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.1.0/mscorlib.dll
/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.1.0/mscorlib.dll
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我怎样才能说服 Roslyn 拿起mscorlibDLL?
如果您尝试为 .NET Core 编译程序集,System.Object则在 中定义System.Runtime,而不是 mscorlib。1此外,在为 .NET Core 编译时,编译器通常使用引用程序集,而不是实际的运行时二进制文件。
所以,简短的回答:为 System.Runtime.dll 创建 MetadataReference。
var nuget = Environment.GetEnvironmentVariable("HOME") + "/.nuget/packages";
MetadataReference.CreateFromFile(nuget + "/system.runtime/4.3.0/ref/netstandard1.5/System.Runtime.dll")
Run Code Online (Sandbox Code Playgroud)
更长的答案
不过,很有可能您不仅需要 System.Runtime。查看正在引用哪些库的更简单方法是检查您自己的应用程序的编译。要查看这一点,请添加一个包引用Microsoft.Extensions.DependencyModel并检查用于编译和应用程序的所有库。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.0.0-*" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="1.1.0" />
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
var references = from l in DependencyContext.Default.CompileLibraries
from r in l.ResolveReferencePaths()
select MetadataReference.CreateFromFile(r);
foreach (var r in references)
{
Console.WriteLine(r.FilePath);
}
Run Code Online (Sandbox Code Playgroud)
1请参阅页面最底部的https://docs.microsoft.com/en-us/dotnet/core/api/system.object。