6

我有一个客户/合作伙伴试图使用我们公开的 COM 功能将他们的应用程序与我们的应用程序链接起来。到目前为止,他们已经有了一个 COM 对象,它代表我们的软件包的一个实例,然后使用我们的 COM 方法根据他们在应用程序中所做的事情以编程方式为用户构建一些东西。它本质上是一个“导出”功能。

他们要求我做的是让用户决定何时关闭实例,但我不知道该怎么做。我的意思是当我们的软件包被加载时,它是可见的并且可以被用户交互。完成后,他们自然会单击右上角的叉号退出软件。这不起作用,因为 COM 对象在他们的应用程序中仍然是“活动的”。我们的软件包只能通过在任务管理器中终止进程来关闭,而通过 COM 加载它的应用程序保持打开状态。一旦他们的应用程序退出,我们的应用程序将自动关闭。由于 COM 调用,他们的应用程序似乎“拥有”了我们的应用程序。

我在 C# 中制作了一个快速演示应用程序,尝试使用Marshal.FinalReleaseComObject(myObject)无济于事的东西。

我意识到将 COM 用于这种事情并不是它的真正用途,但希望有某种解决方法?客户/合作伙伴使用的是 VB.NET,但 C# 很好。

4

1 回答 1

3

您遗漏了一些关于您自己的应用程序的关键信息,包括最重要的是您如何实现向客户端应用程序公开的 COM 接口。您的描述对我来说是一个危险信号的一个方面是您的应用程序的实例化。您说客户端应用程序是“使用 VB 通过引用我们的 exe 来启动新进程”。如果您已正确实施并注册了您的 COM 服务器,则不需要这样做。让我告诉你我将用来完成你所要求的架构,希望这对你有用。

首先,如果您想在单独的进程中提供 COM 对象,正确的方法是实现 COM 进程外服务器。使用进程外服务器,当客户端通过 COM 请求您的接口之一时,COM 将自动启动您的应用程序。进程外服务器的部分实现要求是在最后一个 COM 客户端释放其最后一个接口指针时自动关闭。

为了从进程外服务器公开用户界面,您需要使用消息循环生成一个单独的单线程单元 (STA) 线程。这将允许您关闭 STA 线程上的任何窗口,包括主窗口,而不会终止您的 COM 服务器。这是因为 COM 服务器实现将运行它自己的多线程单元 (MTA) 消息循环线程,以支持 COM 进程外调用。MTA线程是主应用线程,当最后一个客户端接口被释放时,服务器会关闭它。

当接口保持未释放时,不应关闭COM 服务器。这意味着客户端应用程序有责任正确发布接口。但是您的 .NET 测试框架应该已经完成​​了这项工作,因此您的实现似乎有些问题。

假设您遵循本指南,您将需要一个计划来处理最后一个客户端界面已发布但您仍然有打开的 UI 窗口的情况。一旦您正确设置了所有内容,这应该不是主要问题。例如,您可以在 UI 打开时简单地引用您自己的界面之一,这将防止 MTA 关闭。

于 2012-05-08T05:23:32.110 回答