如何使.NET不使用已注册的TLB封送对COM方法的调用?

如何使.NET不使用已注册的TLB封送对COM方法的调用?,.net,com,marshalling,typelib,tlbimp,.net,Com,Marshalling,Typelib,Tlbimp,当前配置为: 主应用程序是非托管的 它包含DLL,其中包含TLB,它描述了暴露于COM模型的函数 为了支持ASMX web服务,它加载.NET framework,并启动为web服务调用提供服务的ASP.NET域 为了服务web服务调用,它需要来自主应用程序的数据。所以,我们 从TLB生成互操作程序集(使用tlbimp.exe),web服务程序集使用此互操作与主应用程序中的COM对象通信 在我们遇到版本问题之前,一切都正常。在同一台计算机上安装两个版本的应用程序(包含两个版本的TLB)时,两个版

当前配置为:

  • 主应用程序是非托管的
  • 它包含DLL,其中包含TLB,它描述了暴露于COM模型的函数
  • 为了支持ASMX web服务,它加载.NET framework,并启动为web服务调用提供服务的ASP.NET域
  • 为了服务web服务调用,它需要来自主应用程序的数据。所以,我们 从TLB生成互操作程序集(使用tlbimp.exe),web服务程序集使用此互操作与主应用程序中的COM对象通信
  • 在我们遇到版本问题之前,一切都正常。在同一台计算机上安装两个版本的应用程序(包含两个版本的TLB)时,两个版本的TLB(例如,2.0和2.1)都将注册,较低版本将停止工作。ProcessMonitor显示,当尝试调用版本2.0实例的web服务时,它会在注册表中查找TLB的GUID,读取带有版本号的所有子项,获取最后一个版本(2.1)并开始读取其内容。之后,它读取2.1版的DLL,在自己的进程内无法进行COM调用——据我所知,这是由于封送处理中的问题

    如何进行互操作,而不需要TLB(至少是注册的TLB)来进行进程内COM调用


    提前谢谢。

    好吧,这是解决问题的方法

    .NET似乎加载TLB来为每个ASP.NET线程构建新的单元(当新线程第一次尝试访问某些COM接口时,一切都会发生)。为此,它似乎使用了CoMarshalInterThreadInterfaceInStream和CogetInterface以及LeaseStream函数。我无法证明这一点,但调用这些函数会产生相同的效果:查询系统注册表并加载最高兼容版本(相同主版本,最高次版本)的TLB。CoGetInterface和LeaseStream行为不受清单的影响

    所以,真正的问题是我们的项目没有遵循微软推荐的版本编号规则:具有相同主版本的COM接口应该是兼容的


    找到的唯一解决方案是拼接:获取LoadTypeLib函数(OleAut32.dll)的地址,并在其开头设置JMP指令。JMP进入我们的实现,检查正在加载的TLB的名称,如果它是已知的TLB之一,则将读取重定向到本地目录。

    哇,这是一个多么骇人的解决方案。为什么不增加typelib的主要数量呢?每天会创建好几次新的构建(当然,并不是所有的构建都不兼容,但是要完全检查兼容性是相当困难的)。主要版本的长度只有2个字节,所以这个解决方案只能工作2年,之后我们还需要其他东西。