Roslyn(二)动态编译DLL和缺少Private.CoreLib的问题

3 篇文章 1 订阅

CoreLib问题

最近学习Roslyn,看如何编译一个Dll来使用,网上有很多Roslyn的文章,但是都有点问题,我编译的DLL加入到别的项目使用,就会提示:

严重性	代码	说明	项目	文件	行	禁止显示状态
错误	CS0012	类型“Object”在未引用的程序集中定义。必须添加对程序集“System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e”的引用。	ConsoleApp1	G:\Github\MMCServer\MMCEngine\ConsoleApp1\Program.cs	14	活动

先放上代码来:

动态脚本:
using System;
    public class MyLib
    {
        public static string GetGreeting()
        {
            return "Ahoy";
        }
    }
生成脚本:
public void writedll()
        {
            string sourceCode = File.ReadAllText(@"c:\Temp\MyLib.cs");
            SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(SourceText.From(sourceCode));

            var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
            Console.Write("dll path :"+ assemblyPath);
          
            List<MetadataReference> list = new List<MetadataReference>()
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(SyntaxTree).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(CSharpSyntaxTree).Assembly.Location)
            };


            CSharpCompilation compilation = CSharpCompilation
                .Create("MyLib")
                .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
                .AddReferences(list)
                .AddSyntaxTrees(syntaxTree);

            EmitResult result = compilation.Emit(@"c:\Temp\MyLib.dll");
            if (!result.Success)
                Console.Out.WriteLine(string.Join(Environment.NewLine, result.Diagnostics.Select(diagnostic => diagnostic.ToString())));
        }

我们运行这个函数后就生成了DLL。

在控制台里运行

然后我们创建一个控制台项目来使用这个MyLib.dll
在这里插入图片描述
代码只有短短的两行

Console.WriteLine("Hello, World!");
Console.WriteLine(MyLib.GetGreeting());

如下图,已经报告出了错误。

错误 CS0012 类型“Object”在未引用的程序集中定义。必须添加对程序集“System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e”的引用。

在这里插入图片描述
在网络找了很多资料一直,大概是DLL编译引用了错误的元数据引用(MetadataReference),应该引用“引用程序集(reference assemblies)”不应该引用“实现程序集(implementation assemblies)”。

那我们只改掉代码,路径里是我的,不同机器和版本可能位置不同,自行修改。

修改后

public void writedll()
        {
            string sourceCode = File.ReadAllText(@"c:\Temp\MyLib.cs");
            SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(SourceText.From(sourceCode));

            var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
            Console.Write("dll path :"+ assemblyPath);
            List<MetadataReference> list = new List<MetadataReference>()
            {
                //MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                //MetadataReference.CreateFromFile(typeof(SyntaxTree).Assembly.Location),
                //MetadataReference.CreateFromFile(typeof(CSharpSyntaxTree).Assembly.Location)
            };

            string dllpath = @"C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\7.0.9\ref\net7.0\";
            foreach (string dll in Directory.GetFiles(dllpath, "*.dll"))
            {
                if (!dll.Contains("VisualBasic"))
                    list.Add(MetadataReference.CreateFromFile(dll));
            }
            
            CSharpCompilation compilation = CSharpCompilation
                .Create("MyLib")
                .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
                .AddReferences(list)
                .AddSyntaxTrees(syntaxTree);

            EmitResult result = compilation.Emit(@"c:\Temp\MyLib.dll");
            if (!result.Success)
                Console.Out.WriteLine(string.Join(Environment.NewLine, result.Diagnostics.Select(diagnostic => diagnostic.ToString())));
        }

运行后,重新生成了DLL,这样就可以直接运行没有报错了。
在这里插入图片描述

最后

当然这里的引用程序集比较粗暴,这里不再探讨。
这个问题让我卡了很久,遇到同样的问题的可以参考借鉴吧。
因为学习中,可能存在错误,还请留言。

#参考
https://github.com/dotnet/core/issues/2082

https://stackoverflow.com/questions/69042106/could-not-load-file-or-assembly-sharedlib-dll-when-dll-is-compiled-by-roslyn

https://stackoverflow.com/questions/53514059/net-core-roslyn-cannot-find-system-decimal-in-assemblies

https://stackoverflow.com/questions/68109143/choose-references-dynamically-in-net-core-for-roslyn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值