.NET进程外COM对象在API调用中共享静态实例

时间:2011-05-26 07:26:56

标签: com static activex vsto out-of-process

我们很难解释我们的情况。

我们有3层申请。引擎是用C ++编码的DLL,然后我们有一个VB6 ActiveX EXE通过API调用访问引擎,在顶层我们有一个Excel Addin(在C#中使用VSTO框架)调用中间层与一个互操作DLL 。此时,从Addin到引擎的每个“连接”都会创建一个新的EXE(VB6使用API​​调用来访问引擎)并且一切正常。 现在我们将中间层移动到.NET,它的工作“大概”很好(它通过我们所有的单元测试)但是,当我们同时打开2个“连接”时我们发现错误(ups,没有单元测试检查这种情况因为这是一种新的行为。 DLL具有静态对象,它在同一进程中的所有实例上共享,并且我们在“连接”之间进行交互。在我们的旧版本中,每个“连接”创建一个新的EXE,进程之间没有内存共享,现在它们是相同的进程,它们共享内存和静态对象。

按照this question的提示操作。我们尝试在C#中构建一个COM EXE来在中间层执行一个进程外对象,但是我们有相同的结果。它们共享静态对象,最后,每个连接都不会创建一个独立的进程。

很明显,但目前还不能负担得起,将API调用移动到ATL或使用句柄将静态对象更改为可实现的引用,并更改所有API调用以获取/设置此处理程序。我查看了MS All-in-one中的所有示例,但我没有找到任何解决方案。也不可能只保留一个连接,每个工作簿可以有一个连接,并且将来我们希望同时探索具有多个连接的Web应用程序。

有什么建议吗?

提前致谢,

3 个答案:

答案 0 :(得分:3)

COM是否为每个COM对象启动新的EXE,或者使用单个EXE来实例化所有对象是由传递给CoRegisterClassObject的flags参数控制的。参见

http://msdn.microsoft.com/en-us/library/ms693407(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/ms679697(v=vs.85).aspx

您需要传递REGCLS_SINGLEUSE或REGCLS_MULTI_SEPARATE标志。

现在,诀窍是传递此标志,因为您可能不直接调用此方法 - 详细信息取决于您如何实现COM EXE。

答案 1 :(得分:2)

从问题中不清楚,但听起来你所拥有的“中间层”是作为VB6 EXE构建的,并且你试图用.net DLL替换它。如果是这样的话,你肯定会得到你描述的行为。

使用VB6 EXE com项目,实例化一个新对象会启动一个新进程。使用.net dll(或者真的是Vb6 dll),你+不会+获得新的进程。

您需要创建一个.net EXE,它就像您的VB6 exe那样公开COM对象,或者(听起来您已经调查过这个),您需要重构EXE对象以正确处理多个实例在一个过程中。

老实说,做后者可能会更好,因为依赖这样的单身通常是一种糟糕的代码味道。但它是一个捏,你应该能够用.net项目复制VB6 exe的行为。你不能在dll中做到这一点。

答案 2 :(得分:1)

您的中间层是否在.Net中创建?如果是,您可能面临的问题是您的COM类是作为本机.net对象而不是COM对象创建的。解决方案通常涉及使用Primary Interop Assemblies。请查看this SO question,看看它是否符合您的问题。