【问题标题】:Revit API - Possible NewtonSoft.Json conflictRevit API - 可能的 NewtonSoft.Json 冲突
【发布时间】:2016-01-11 14:39:14
【问题描述】:

我正在尝试创建一个可以访问云端并检索数据的扩展程序,这是一个简单的请求。使用加载项管理器时它工作得完美无缺,但是当我分发给其他用户时,我使用的 NewtonSoft.Json 版本(7.0.1)和我在 Revit 程序中找到的版本似乎有冲突文件 (5.0.8)。

完整的错误信息是:

[窗口标题] 外部命令的命令失败

[主要指令] Revit 无法完成外部命令。 联系供应商寻求帮助。他们提供给的信息 Revit 关于他们的身份:icubY。

[扩展信息] Revit 遇到了一个 System.IO.FileNotFoundException:无法加载文件或程序集 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' 或其依赖项之一。

这是一个共享 DLL,它封装了从 API 到 APP 的所有内容(带有安全令牌、标头、cookie),因此单独的版本会很痛苦。

我真的需要使用旧版本才能使用吗?还有什么想法吗?

【问题讨论】:

  • 您能否尝试仅将此 JSON 引用设置为 (CopyLocal=True) 和 (UseSpecificVersion=True)
  • 嗨@AugustoGoncalves,这是默认开启的,因为 NewtonSoft 来自 NuGet,仍然没有运气

标签: revit revit-api


【解决方案1】:

首先,我将从Fuslogvw.exe 工具开始,看看加载程序集时会发生什么。

AddInManager 使用Assembly.LoadFile 加载插件,然后挂钩到AppDomain.CurrentDomain.AssemblyResolve 事件以解决依赖关系。也许您可以使用相同的技术来加载您的 Newtonsoft.Json 程序集。

【讨论】:

  • 是的!效果很好!通过 AssemblyResolve 事件,我能够从我的 AddIn 加载 Json,而不是 Revit 上的版本。
【解决方案2】:

我在 IExternalApplication.OnStartup 方法中手动加载我的所有依赖项。您遇到的问题是因为 Revit 在包含 Revit.exe 的文件夹中查找任何依赖项,而不是在您的插件目录中。

如果您无法让 AssemblyResolve 事件起作用,请尝试以下操作:

通过使用检索插件的目录 string location = Assembly.GetAssembly(typeof(YourIExternalApplicationClass)).Location;, 然后使用string dir = Path.GetDirectoryName(location);

然后您可以使用string dllPath = Path.Combine(dir, "DLLName.dll");获取每个依赖项的路径

最后,使用Assembly.LoadFrom(dllPath);加载每个DLL

【讨论】:

    【解决方案3】:

    我做了更多的研究,因为我没有完全理解上面的解决方案。我认为一个非常简单的解决方案是explained here

    您只需在 Visual Studio 项目中将引用 (newtonsoft.json) 设置为特定版本 = true,然后使用您的 revit 加载项 .dll 将该引用复制到加载项文件夹中

    当您分发给用户时,他们将需要 newtonsoft.json 库以及您的加载项 .dll,这并不理想但可行(刚刚测试过,这对我有用)

    【讨论】:

      【解决方案4】:

      所以我在我正在处理的一个项目中同样遇到了这个问题。在对这个问题进行了大量挖掘之后,我觉得我对正在发生的事情有了一个很好的把握。

      如前所述,Revit 使用Assembly.LoadFile 命令加载装配体。这意味着所有加载项程序集都加载到相同的AppDomain 中。如果您想将事件处理程序添加到 AppDomain.CurrentDomain.AsseblyResolve 以防止加载项中的冲突,这并不理想。这是因为AssemblyResolve 是一个不寻常的事件,它需要一个程序集作为返回项目。这意味着,如果您有多个事件处理程序附加到AssemblyResolve,则返回非空程序集的第一个事件处理程序将是使用的事件处理程序,因此如果多个加载项尝试解析相同的程序集(例如在像 Newtonsoft.Json 这样的普通程序集的情况下)。

      例如,如果您安装了 Dynamo,Dynamo 还会向 AssemblyResolve 添加一个事件处理程序,尝试解析 Newtonsoft.Json 并从 Dynamo 程序文件目录加载它叫。就我而言,我需要 Newtonsoft.Json 版本 7.0.0.0,但在我的计算机上安装了 Dynamo 0.9 后,它返回的是 Newtonsoft.Json 版本 4.5.0.0。考虑到我在理论上完美地处理了解决方案,但我的程序集解决事件在我需要时没有触发,这令人难以置信的混乱。

      话虽如此,在这种特定情况下,您无能为力。解决这个问题的一些迂回方法是:

      -找到一种在 Dynamo 之前加载加载项的方法(或任何正在解析您希望解决的事件的程序集)并更好地处理解析(即,在解析之前确保它是您当前正在运行的应用程序组装问题)。注意:在 Revit 启动时查看 procmon.exe 输出后,Revit 似乎首先按字母顺序从“C:\ProgramData\Autodesk\Revit\Addins\”文件夹加载插件,然后从“C: \ProgramData\Autodesk\ApplicationPlugins”文件夹按字母顺序排列。

      -联系有冲突的插件制造商,请他们解决问题。

      -针对我的问题,只需将 dynamo 升级到 1.2 版即可解决冲突。

      我已经阅读了有关创建您自己的 AppDomain 并将您需要的所有程序集加载到其中然后执行您想要的操作而不会发生冲突的信息,但我无法让它为自己工作。

      注意:不要浪费时间弄乱特定库的 application.config 文件。 Revit 将仅检查 Revit.exe.config 中的装配探测路径和相关装配信息。我也不建议修改它。

      【讨论】:

        猜你喜欢
        • 2013-10-14
        • 1970-01-01
        • 2013-07-20
        • 2020-06-24
        • 2016-02-29
        • 1970-01-01
        • 2019-01-10
        • 2017-02-09
        • 1970-01-01
        相关资源
        最近更新 更多