Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
引用Newtonsoft.Json.dll时,在mono下运行时编译C#代码失败_C#_Json.net_Mono - Fatal编程技术网

引用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.Json
NuGet
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需要时间,但仍然是值得的。

您有两种可能:

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

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


  • 从错误消息中,我猜他找到了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)。再次工作。呸!很高兴我找到了这根线!谢谢