是否可以通过路径而不是GUID在托管项目中引用COM DLL?

时间:2009-07-09 20:35:38

标签: .net com msbuild

我有一个托管(实际上是asp.net)项目,它引用了一个COM DLL。现在,.csproj中的引用如下所示:

<COMReference Include="thenameinquestion">
  <Guid>{someguidhere}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>tlbimp</WrapperTool>
</COMReference>

这很有效,但是它有一个令人遗憾的结果是DLL需要在构建机器上注册,这意味着(除其他外)构建在同一个DLL上使用不同版本的DLL的项目的多个版本是不方便的建造机器。

MSDN显示ResolveComReference任务,看起来它是正确的,但我的google-search-fu还不够好,无法提供其使用的实际示例。有可能做我想要的吗?我是在正确的轨道上吗?

4 个答案:

答案 0 :(得分:9)

当您引用COM DLL时,Visual Studio会自动为其生成互操作程序集。我发现手动控制这个过程是解耦COM和.NET构建的好方法。

  1. 使用tlbimp.exe为COM DLL创建自己的互操作程序集。有关命令行参数,请参阅MSDN
  2. 在.NET项目中引用您的互操作程序集,而不是 COM DLL。
  3. 执行此操作后,您不再需要在构建.NET解决方案时在计算机上注册COM DLL,只需要您的互操作程序集。

    互操作程序集可以永久保存在文件夹中,直到(a)COM DLL破坏二进制兼容性,或(b)进行COM代码实际使用的COM接口更改。

    如果您有不同版本的COM DLL,它们都是二进制兼容的,那么请根据包含.NET代码所需接口的最早版本编译互操作程序集。然后,您将不必更新不同版本的互操作程序集。

    此外,如果您可以假定COM DLL已经安装在目标计算机上,则无需在安装程序中包含COM DLL。

答案 1 :(得分:3)

正如John Fisher指出的那样,您正在寻找Registration-Free COM Interop。关于此问题已经有很多问题,请查找“标记”regfreecom以及密切相关的标记sxs

然而,你很容易看出,这可能是一个棘手的舞台,特别是:

  • 在Windows XP上似乎存在影响此问题的confirmed错误,有关详细信息,请参阅here。虽然已经提供了一个修补程序,但只要您仅定位到受控环境,这可能就足够了,例如,你的构建机器。
  • 由于您的目标是ASP.NET,因此您应该意识到与桌面应用程序这意味着您无法控制托管进程,托管进程可能因部署平台而异。这意味着提供所需的应用程序清单以控制主机内COM组件的运行时绑定和激活并不容易(请参阅下一个可能的替代方案)。
  • ASP.NET 2.0似乎通过为非托管组件删除并排功能而使事情变得更复杂。我没有找到这方面的官方消息来源,但Isolating ASP .Net 2.0 Applications的作者似乎已经知道了;他至少提供了一种解决方法,虽然看起来很复杂,但可能很脆弱。

总结一下,我想强调一点,'免注册COM互操作'可以非常有用,可以轻松解决很多场景。对于您的特定场景和环境(托管的ASP.NET),它仍然可能不会使事情变得更容易甚至可能。

祝你好运,请告诉我们你是否成功了!

答案 2 :(得分:2)

本文介绍如何免费注册激活COM组件。也许它会有所帮助:http://msdn.microsoft.com/en-us/library/ms973913.aspx

答案 3 :(得分:-1)

看起来不可能 - Visual Studio只会查看引用中提到的GUID,它不关心那里暗示的路径。

我们的日常构建服务器遇到了类似的问题 - 除非注册了COM服务器,否则COM客户端无法编译。我们刚刚将注册/取消注册添加到构建序列 - 它注册(regsv32)组件,然后VS从命令行运行,并在VS完成后立即取消注册组件(regsvr32 -u)。运行顺利。