引用Newtonsoft.Json.dll时,在mono下运行时编译C#代码失败
我们的软件是用引用Newtonsoft.Json.dll时,在mono下运行时编译C#代码失败,c#,json.net,mono,C#,Json.net,Mono,我们的软件是用C#编写的,运行.netframework4.7.2。我们的用户可以使用我们软件中内置的脚本编辑器,用C#编写自己的用户脚本。为了实现这一点,我们正在使用.Net组件CodeDomProvider。为了方便地使用JSON,我们希望在用户脚本中引用Newtonsoft.JSON.dll。这是通过添加对CodeDomProvider的CompilerParameters的引用来实现的。通过使用最新的Newtonsoft.JsonNuGetpackage(12.0.3),Newtonso
C#
编写的,运行.netframework4.7.2
。我们的用户可以使用我们软件中内置的脚本编辑器,用C#编写自己的用户脚本。为了实现这一点,我们正在使用.Net组件CodeDomProvider
。为了方便地使用JSON,我们希望在用户脚本中引用Newtonsoft.JSON.dll
。这是通过添加对CodeDomProvider的CompilerParameters的引用来实现的。通过使用最新的Newtonsoft.JsonNuGet
package(12.0.3),Newtonsoft.Json被添加到我的应用程序中
以下是此设置的最低示例:
using System;
using System.CodeDom.Compiler;
using System.IO;
namespace ScriptingUnix
{
class Program
{
static void Main(string[] args)
{
try
{
string output;
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
output = "/tmp/MyUnixTest.dll";
}
else
{
output = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyUnixTest.dll");
}
CompilerParameters parameters = new CompilerParameters
{
GenerateInMemory = false,
IncludeDebugInformation = true,
OutputAssembly = output
};
using (CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp"))
{
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("Newtonsoft.Json.dll");
CompilerResults results = codeProvider.CompileAssemblyFromSource
(
parameters,
"using System;\nusing Newtonsoft.Json.Serialization;\nusing Newtonsoft.Json.Linq;\n class Program\r\n{\r\n static void Main(string[] args)\r\n {\r\n \r\n }\r\n}"
);
foreach (CompilerError compilerError in results.Errors)
{
Console.WriteLine(compilerError);
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
}
}
此设置在Windows上的.Net Framework下运行良好。问题是,我们还提供了一个在(Arch)-Linux上运行Mono的软件版本(Linux 4.19.80-1-Arch armv7l,Mono JIT编译器版本6.0.0(makepkg/6256b82d62f Wed Sep 2019 05:04:08 AM UTC)),如果使用mono运行相同的代码,将导致出现错误CS0006:找不到元数据文件Newtonsoft.Json.dll
我已经尝试将以下内容添加到我的应用程序的app.conf中,但没有帮助。另外,重新安装NuGet
软件包也无济于事。将Newtonsoft.Json.dll
添加到GAC不起作用(将程序集Newtonsoft.Json.dll添加到缓存失败,原因是失败:指定的文件不是有效的程序集。
)。在尝试使用app.conf时,我观察到错误消息更改为错误CS0009:元数据文件/opt/Newtonsoft.Json.dll不包含有效的元数据:元数据文件/opt/Newtonsoft.Json.dll不包含有效的元数据
。这就是为什么我猜他找到了dll,但需要额外的有效数据。我想到了某种dll.conf
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
有人对如何实现这一点有什么建议吗?您的代码示例在.NET 4.7上运行得很好,但由于您运行的是Mono,这里有一些可能的解决方案:
编译器需要知道从何处获取此文件。如果您说需要引用
System.dll
,编译器可能会尝试在中找到它(它确实找到了)。当您引用未知库,如
Newtonsoft.Json.dll
时,它尝试搜索GAC,但失败。然后它可能会在工作目录中找到它
解决方案#1:
尝试设置库的完整路径
解决方案#2:
在GAC中尝试Newtonsoft.Json.dll
解决方案#3:
试试.NETCore!这是惊人的,跨平台和3.1版本现在有开源WinForms和WPF
我知道将代码移动到.NET Core 3需要时间,但仍然是值得的。您有两种可能:
从错误消息中,我猜他找到了Newtonsoft.Json.dll,但他想要一些额外的元数据。我还尝试将dll添加到GAC,但gacutil报告:
将程序集Newtonsoft.Json.dll添加到缓存失败:指定的文件不是有效的程序集。
。转换到.NETCore是有计划的,但还不可能,所以这对我来说不是一个解决方案。将根据您的评论更新问题。您认为这将解决问题的原因是什么?与Mono 6.0.0或Newtonsoft.Json 11.0到12.0.3相比,Mono 6.6中的哪些变化应该改变行为?因为我已经测试并解决了这个问题。可能dll格式已经改变,新mono为新格式添加了支持。我刚刚使用11.0.2重新测试了它,并将绑定重定向到
。现在它按预期工作。非常感谢@andrus就我而言,我不得不留在Newtonsoft.Json 12。将容器中的mono更新为最新版本(6.8)。再次工作。呸!很高兴我找到了这根线!谢谢