在 OSX 上使用 .NET Core 从代码中调用 Roslyn:"No assembly containing System.Object was found"
Invoking Roslyn from code with .NET Core on OSX: "No assembly containing System.Object was found"
我正尝试在 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);
}
}
}
}
当我 运行 这段代码时,(test.dll
保持为空并且) WriteLine
打印出一个 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
所以看起来 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
我做错了什么?我怎样才能说服 Roslyn 选择 mscorlib
DLL?
如果您尝试为 .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")
更长的答案
不过,很有可能您想要的不仅仅是 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>
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);
}
1参见页面底部的 https://docs.microsoft.com/en-us/dotnet/core/api/system.object。
我正尝试在 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);
}
}
}
}
当我 运行 这段代码时,(test.dll
保持为空并且) WriteLine
打印出一个 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
所以看起来 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
我做错了什么?我怎样才能说服 Roslyn 选择 mscorlib
DLL?
如果您尝试为 .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")
更长的答案
不过,很有可能您想要的不仅仅是 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>
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);
}
1参见页面底部的 https://docs.microsoft.com/en-us/dotnet/core/api/system.object。