com -互操作程序集在从Vb调用时找不到本机(. net)依赖项



我有一个c# com -互操作程序集,我从Visual Basic 6应用程序调用。这个程序集发出HTTP请求来发送和检索JSON。

当使用c#测试客户端进行测试时,程序集可以正常工作。

然而,当使用它与VB6应用程序,返回以下错误:

"无法加载文件或程序集" Newtonsoft。Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'或其依赖项之一。系统找不到指定的文件。"

Newtonsoft.Json.dll与COM-Interop DLL (TLB)位于同一个文件夹中。

需要显式加载Newtonsoft.Json.dll吗?或者放到GAC里?

Hans很好地解释了为什么会发生这种情况。让我提供一个解决方案,使这项工作必须在GAC中注册Json DLL或将其复制到VB6 EXE目录。

在com可见的c#库中,我们可以告诉。net运行时环境在c#库的目录中搜索Json DLL,而不是"通常"的路径。我们通过将自己的处理程序附加到AssemblyResolve事件来做到这一点:

AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
{
    // We only want this workaround for one particular DLL
    if (e.Name != "Newtonsoft.Json")
        return null;
    var myLibraryFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    var path = Path.Combine(myLibraryFolder, "Newtonsoft.Json.dll");
    return Assembly.LoadFrom(path);
};

关于此解决方案的注意事项:

  • 此代码仅适用于在执行任何可能导致抖动加载JSON库之前在c#库中执行。例如,在你的VB6进程中,无论是你的库还是任何其他。net库都必须在执行此代码之前从JSON库中调用任何引用类型的方法。

  • 您可以修改整个过程的行为,而不仅仅是您的库。如果你的VB6进程使用另一个使用JSON的库,你的"重定向"也会影响其他库。

这是一个标准的DLL Hell问题,它是由使用Regasm.exe的/codepage选项引起的。或者,更常见的是,Project> Properties> Build选项卡> Register for COM interop复选框。两者都做同样的事情,它们将DLL的路径写入注册表。当您忙于开发和测试项目时,这是一个非常好的选择,它避免了每次进行更改时都必须将DLL重新注册到GAC中。

但是没有做的是帮助CLR找到任何依赖项。正常的探测规则仍然有效,它在存储EXE的目录中查找appname.exe.config文件。首先在GAC中查找,然后在EXE路径中查找依赖项。配置仍然在DLL地狱的通常受害者的控制之下,无论谁必须维护EXE。通常是终端用户。因此,显式地,它不查找您的[ComVisible] DLL存储的目录。

这是一种温和的DLL地狱,只是一个普通的文件未找到的不幸。比找到文件名正确但版本错误的文件要温和得多。一般来说,Newtonsoft.Json.dll有一个严重的问题,大约有35个版本。拥有如此多的版本,而且它是一个如此受欢迎的库,也带来了另一种麻烦,该程序使用另一个也使用DLL的COM服务器。但几乎不可避免的是一个不同的版本。往往发生在你宣布项目完成很久之后。其中一个会输,50%的几率是你。对于最终用户来说,100%的几率。

是的,GAC解决了这个问题。每个库都得到他们要求的版本。理想情况下,Newtonsoft会用一个将DLL部署到GAC中的安装程序为您解决这个问题。但这并不是开源库作者想要提供的那种承诺。他们想(也需要)把它变成你的问题。微软做到了这一点,但他们也有Windows Update来确保关键错误和安全修复得到部署。并且有大量的人致力于确保任何新的版本总是向后兼容原始版本,这样版本号就不必改变了。

请注意,您可以利用微软的承诺。您还可以使用DataContractJsonSerializer和JavascriptSerializer类来完成这项工作。作为框架的一部分,他们很少出错。

同时,请记住只是一个文件未找到的问题。您不必在开发机器上使用GAC,如果不这样做更好,将文件复制到正确的位置以保持CLR满意同样容易。该目录与您的VB6测试程序相同。而且,额外的怪癖与VB6,进入C:Program Files (x86)Visual StudioVB6,如果你想使用VB6调试器。在部署时一定要使用GAC。

相关内容

  • 没有找到相关文章