强制.NET互操作使用本地COM DLL

8
是否可以强制使用一个Interop程序集来引用其关联COM DLL的本地副本?
以下是情况:
我有一个.NET应用程序引用了一个Interop程序集(Interop.OTAClient.dll),它是HP质量中心自动化API COM DLL(OTAClient.dll)的Interop。我对COM并不是很了解,但据我所知,Interop程序集通过在注册表中查找GUID引用来查找COM类,而不是指向特定文件。
我的问题是,注册表键所指向的OTAClient.dll副本会根据我刚刚登录浏览器的QC版本而被覆盖,这些DLL的不同版本彼此不兼容。 .NET应用程序只会连接到QC的特定版本,因此我不能让COM DLL以这种方式变化。
如果您有任何建议,将不胜感激,因为这种行为确实令人恼火。我看到了其他关于COM互操作问题的问题,但它们似乎都是关于强制使用GAC中的一个本地版本的Interop DLL,而不是涉及实际的COM DLL的这种特定情况。
3个回答

10

Pavel指引了我正确的方向,所以我将把他的回答标记为答案。为了让其他人也受益,以下是我的做法:

  1. 添加对原始OTAClient.dll的引用,并让Visual Studio生成Interop库。
  2. 在解决资源管理器中右键单击所引用的库,然后单击“属性”。接下来将隔离(Isolated)设置为True。这会使VS生成一个清单文件,告诉您的程序在本地查找COM库,而不是在注册表中列出的库。
  3. 根据我的情况,我还必须引用Quality Center的WebClient.dll,并将其隔离(Isolated)设置为True。虽然此DLL不直接被使用OTA API的应用程序使用,但似乎被OTAClient.dll所引用。

通过这种方式,您可以登录和注销QC实例,而这些实例的版本与您的应用程序所使用的版本不同,而不会破坏它。在我的情况下,我有一个本地QC实例,它是v9版本的,并用于特定项目的自动化(由于种种原因,它进行了大量的定制以满足我们的需求,具有大量的截屏存储空间等等),而且我的应用程序连接到该实例。然而,对于手动测试,我还需要使用IE登录到另一个位置的v9.2实例。如果我之前已经登录到了v9.2实例,则需要在IE中打开v9实例并让其重新下载控件,然后才能再次运行我的应用程序…现在我就不需要这样做了 :)。


5

嗨,Pavel。感谢提供的链接 - 我按照示例操作了一遍,VS生成了OTAClient的清单条目,就像预期的那样。然而,如果浏览器应用程序最后使用了DLL的更新版本,我仍然看到相同的症状。你认为OTAClient可能有自己的依赖项,这些依赖项也被新版本覆盖了吗?如果是这样,你有什么建议来处理这个问题吗? - Xiaofu
如果这些依赖项本身是COM组件,那么可能是可行的。如果是这样,您应该以类似的方式处理它们(以便最终获得一个自给自足的库集合)。 - Pavel Minaev

1
一个小例子展示了当我们将Isolated属性设置为true后,Web.config如何更改,这将帮助其他人理解当我们将Isolated属性设置为true时实际上发生了什么。VS实际上会在您的代码中输入几行代码,以便它将使用特定CLSID的com Dll。
实际上,我在同一台服务器上有两个.Net应用程序,其中一个应用程序使用Quality center 10.0 Dll,另一个升级到quality center ALM 11.0。因此,在同一台服务器上,我们无法注册具有相同名称的DLL。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接