c# - 在 .NET 中释放 COM 对象的 "ownership"

标签 c# vb.net com

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

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

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

我意识到将 COM 用于此类事情并不是真正的目的,但希望有某种解决方法吗?客户/合作伙伴使用的是 VB.NET,但 C# 没问题。

最佳答案

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

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

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

COM 服务器不应在接口(interface)未释放时关闭。这意味着客户端应用程序有责任正确释放接口(interface)。但是您的 .NET 测试框架应该已经做到了这一点,因此您的实现似乎有些不对。

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

关于c# - 在 .NET 中释放 COM 对象的 "ownership",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10417686/

相关文章:

c# - slider 大小变化

c# - WinDbg .foreach 通过引用类型获取字段值

database - 如何使用 vb.net 备份 PostgreSQL

.net - VB.Net 编码指南

windows - activex 控件和 activex 对象有什么区别?

c# - 在 Unity3D 中制作渐变并根据该渐变更改颜色 - C# 脚本

c# - 十六进制字符串到字节数组 C#

vb.net - 有没有更快的方法将位图像素转换为灰度?

c++ - 如何为虚函数设置对齐方式?

vb.net - .NET & CreateObject,COM对象使用谁的内存?