我已经创建了一个类库项目,并安装了Newtonsoft.Json NuGet包.此操作添加了一个app.config文件,其中包含:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
Run Code Online (Sandbox Code Playgroud)
然后我让类库COM可见:
当我尝试在另一个C#WinForms项目中使用我的类库时,我收到了错误:
System.IO.FileLoadException:无法加载文件或程序集"Newtonsoft.Json,Version = 4.5.0.0,Culture = neutral,PublicKeyToken = 30ad4fe6b2a6aeed"或其依赖项之一.定位的程序集的清单定义与程序集引用不匹配.(HRESULT异常:0x80131040)
直到我在WinForms项目中添加了相同的app.config行.
现在我正在尝试在Microsoft Word VBA开发人员中使用我的程序集(通过COM引用),我收到了相同的错误,但是我无法为Microsoft Word制作app.config文件,是吗?有什么办法,这个问题怎么解决?
提前致谢!
是的,这是一个标准的DLL Hell问题,当你进行.NET程序集[ComVisible]时,你会遇到这个问题.CLR使用其常规方式查找依赖程序集,这些规则在COM中不会更改.它首先查看GAC,然后查看EXE所在的目录.它不是看在你的[标记有ComVisible特性]组件所在的目录.否则使用Fuslogvw.exe很容易看到的东西,请务必练习它.
这个问题有多种解决方案,没有一种是理想的,所以你必须自己选择最适合自己的方案.你应该强烈追求的第一件事是摆脱.config文件.该<bindingRedirect>总是产生,但往往是不必要的.只有在引用多个Nuget包时才会真正需要它们,并且他们不同意使用的是什么版本的Newtonsoft.Json.dll.如果这是一个问题,那么只有部署到Office文件夹是实用的,请参阅最后一个项目符号.
将所有内容部署到GAC.这通常是COM的理想解决方案,它通常具有强大的DLL Hell问题,因为注册是机器范围的.这使得部署更新变得危险,您可能会在一个程序中修复问题但会破坏另一个程序.缺点是安装要求.将Newtonsoft.Json.dll放入GAC中的可疑做法是一个具有相当不透明的版本历史并被许多其他程序使用的程序集.非零赔率您将破坏使用它的另一个应用程序,因为它现在将副本加载到GAC而不是其本地副本.FUD强大到足以避免这种情况.
使用ILMerge,因此您只有一个DLL.并不总是有效,它无法处理混合模式程序集,也无法处理绑定重定向.尝试一下,你会很快发现.除此之外,唯一的缺点是额外的构建步骤.
订阅AppDomain.CurrentDomain.AssemblyResolve事件并帮助CLR找到依赖项.当你暴露有限数量的类或只有少数类有依赖时,实用.最好在类的静态构造函数中订阅事件,以便尽早发生.一定要做一次.确保在没有调试器的情况下测试Release版本,在任何代码开始运行之前,抖动可能需要依赖项.
将依赖项复制到Office安装文件夹中.这就是CLR检查GAC后的目标.如果您需要bindingRedirect,则还需要将配置文件复制到那里,重命名为Excel.exe.config以匹配Office程序名称.缺点是管理员不喜欢你弄乱该文件夹.还有两个程序执行此操作的问题,第二个覆盖您的DLL或.config文件,可能是您完成项目多年后.不是你的问题,无论如何你都会收到一个难看的电话.