3

很难解释我们的处境。

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

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

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

有什么建议吗?

提前致谢,

4

3 回答 3

3

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

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。

于 2011-06-06T17:12:36.997 回答
2

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

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

您要么需要创建一个 .net EXE 来像 VB6 exe 一样公开 COM 对象,或者(听起来您已经对此进行了调查)您需要重构您的 EXE 对象以正确处理单个内​​的多个实例过程。

老实说,后者可能会更好,因为像这样依赖单例通常是一种不好的代码气味。但它很紧要,您应该能够使用 .net 项目复制 VB6 exe 的行为。你只是不能在 dll 中做到这一点。

于 2011-05-26T15:02:50.887 回答
1

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

于 2011-06-07T20:33:40.933 回答