Revit API - 可能与NewtonSoft.Json发生冲突

时间:2015-10-13 18:02:48

标签: revit revit-api

我试图创建一个转到云端并检索数据的扩展,简单的请求。使用外接程序管理器时它完美无瑕,但是当我分发给其他用户时,似乎与使用(7.0.1)的NewtonSoft.Json版本和我在中找到的版本存在冲突。 Revit Program Files(5.0.8)。

完整的错误消息是:

  

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

     

[主要说明] Revit无法完成外部命令。   请联系提供商以获取帮助。他们提供的信息   关于他们的身份的修改:icubY。

     

[扩展信息] Revit遇到了一个    System.IO.FileNotFoundException:无法加载文件或程序集   ' Newtonsoft.Json,版本= 6.0.0.0,文化=中立,   公钥= 30ad4fe6b2a6aeed'或其中一个依赖项。

这是一个共享DLL,它封装了从API到APP的所有内容(带有安全令牌,标题,cookie),因此分离的版本将是一个真正的痛苦。

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

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

如果你无法使AssemblyResolve事件发挥作用,那么试试这样的事情:

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

然后,您可以使用string dllPath = Path.Combine(dir, "DLLName.dll");

获取每个依赖项的路径

最后,使用Assembly.LoadFrom(dllPath);

加载每个DLL

答案 2 :(得分:1)

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

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

当你分发给用户时,他们需要newtonsoft.json库以及你的插件.dll这是不理想但可行的(只是经过测试,这对我有用)

答案 3 :(得分:1)

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

如前所述,Revit使用Assembly.LoadFile命令加载程序集。这意味着所有加载项程序集都加载到同一AppDomain中。如果您想要向AppDomain.CurrentDomain.AsseblyResolve添加事件处理程序以防止加载项发生冲突,那么这并不理想。这是因为AssemblyResolve是一个不常见的事件,需要将Assembly作为返回项。这意味着如果你有多个事件处理程序附加到AssemblyResolve那么返回非null程序集的第一个事件处理程序将是使用的事件处理程序,因此如果多个加载项试图解析相同的事件处理程序汇编(例如在像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以获取程序集探测路径和相关的程序集信息。我也不建议修改它。

相关问题