繁体   English   中英

引用 Newtonsoft.Json.dll 时,在运行时在单声道下编译 C# 代码失败

[英]Compiling C# code at runtime under mono fails when referencing Newtonsoft.Json.dll

我们的软件是用C#编写的,运行.Net-Framework 4.7.2 我们的用户可以使用我们软件中内置的脚本编辑器,用 C# 编写他们自己的用户脚本。 为了实现这一点,我们使用了 .Net 组件CodeDomProvider 为了能够以简单的方式使用 JSON,我们希望在我们的用户脚本中引用Newtonsoft.Json.dll 这是通过添加对 CodeDomProvider 的 CompilerParameters 的引用来完成的。 Newtonsoft.Json 通过使用最新的 Newtonsoft.Json NuGet包 (12.0.3) 添加到我的应用程序中。

这是此设置的最小示例:

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 25 Sep 2019 05 UTC 时间 :04:08 AM)),其中使用 mono 运行相同的代码会导致error CS0006: Metadata file Newtonsoft.Json.dll could not be found

我已经尝试将以下内容添加到我的应用程序的 app.conf 中,但这没有帮助。 重新安装NuGet包也没有帮助。 Newtonsoft.Json.dll添加到 GAC 不起作用(失败, Failure adding assembly Newtonsoft.Json.dll to the cache: The file specified is not a valid assembly. )。 在尝试使用 app.conf 时,我观察到错误消息更改为error CS0009: Metadata file /opt/Newtonsoft.Json.dll does not contain valid metadata: Metadata file /opt/Newtonsoft.Json.dll does not contain valid metadata 这就是为什么我猜他找到了 dll 但需要额外的、有效的 metadata。 我想到了某种 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>

有没有人有关于如何让它工作的提示?

你有两种可能:

  1. 使用来自 github 的最新 Mono (6.6)。 如果包不可用,则编译它。

  2. 将 Newtonsoft.Json 降级到 11.0 版。 如果需要,请使用绑定重定向。

您的代码示例在 .NET 4.7 上运行良好,但由于您运行的是 Mono,因此这里有一些可能的解决方案:

编译器需要知道从哪里得到这个文件。
如果你说你需要引用System.dll - 编译器可能会尝试在GAC中找到它(它确实找到了)。
当您引用像Newtonsoft.Json.dll这样的未知库时,它会尝试搜索 GAC 并失败。 然后它可能试图在工作目录等中找到它。

解决方案#1:

尝试设置库的完整路径;

解决方案#2:

尝试在GAC中注册Newtonsoft.Json.dll

解决方案#3:

试试 .NET Core! 太棒了,跨平台和 3.1 版本现在有开源 WinForms 和 WPF!

我知道将代码迁移到 .NET Core 3 需要时间,但仍然值得。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM