【问题标题】:Could not load file or assembly in COM visible class library C#无法在 COM 可见类库 C# 中加载文件或程序集
【发布时间】:2016-05-29 00:15:30
【问题描述】:

我创建了一个类库项目,并安装了 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>

然后我让类库 COM 可见:

当我尝试在另一个 C# WinForms 项目中使用我的类库时,我收到了错误:

System.IO.FileLoadException:无法加载文件或程序集“Newtonsoft.Json,版本=4.5.0.0,Culture=neutral,PublicKeyToken=30ad4fe6b2a6aeed”或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。 (HRESULT 异常:0x80131040)

直到我在 WinForms 项目中添加了相同的 app.config 行。

现在我正在尝试在 Microsoft Word VBA 开发人员中使用我的程序集(通过 COM 引用),我遇到了同样的错误,但我无法为 Microsoft Word 创建 app.config 文件,可以吗?有什么办法,这个问题怎么解决?

提前致谢!

【问题讨论】:

  • 我认为您引用的程序集在您的新项目中缺少 Json.dll。要对此进行测试,您可以手动将 json.dll 添加到新项目的输出文件夹中。
  • 您是否尝试过使用发布商政策?这应该将重定向应用于尝试使用旧版本的“所有应用程序”。 msdn.microsoft.com/en-us/library/dz32563a(v=vs.110).aspx
  • 不,我没有。我会尽力让你知道结果。谢谢。

标签: c# .net


【解决方案1】:

是的,这是您在制作 .NET 程序集 [ComVisible] 时会遇到的标准 DLL Hell 问题。 CLR 使用其正常方式查找依赖程序集,这些规则在 COM 中不会更改。它首先在 GAC 中查找,然后在 EXE 所在的目录中查找。它查看您的 [ComVisible] 程序集所在的目录。否则使用 Fuslogvw.exe 很容易看到的东西,一定要练习一下。

这个问题有多种解决方案,没有一个是理想的,所以你必须选择最适合你自己的一个。您应该强烈追求的第一件事是摆脱 .config 文件。 &lt;bindingRedirect&gt; 总是会生成,但通常是不必要的。只有当您引用多个 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 文件,可能在你完成项目几年后。不是你的问题,反正你会接到一个丑陋的电话。

【讨论】:

    猜你喜欢
    • 2020-11-21
    • 2023-03-21
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    相关资源
    最近更新 更多