我创建了一个 C# COM DLL,它本质上是一个增强的进度条,它在新线程 上运行 System.Windows.Forms.Application.Run() 以显示带有对话框的表单。要使用 VBA 在第三方应用程序中使用它,您可以执行以下操作:
Set pg = CreateObject("MyNS.MyProgressBar")
pg.ShowBar()
.
.
pg.Progress = 0.5
.
.
pg.ShutDownBar()
问题是用户能够在到达 pg.ShutDownBar() 之前关闭应用程序(使用 File->Quit 或类似方法)。如果用户这样做,pg.ShutDownBar() 永远不会被调用,结果是虽然应用程序的窗口被隐藏,但它仍然出现在任务管理器进程中。
所以我的问题是: 有什么方法可以检测父应用程序是否已关闭,然后在 c# 中中止进度条的线程?
我已经在启动对话框线程的主线程上尝试了 System.Windows.Forms.Application.ThreadExit 和 System.Windows.Forms.ApplicationExit,但是当通过 COM 访问对象时这些事件似乎没有被引发(尽管它们当我在 .NET 中创建对象时被调用)...
谁能提供一些建议?
最佳答案
这是 COM 引用计数工作方式的问题。除非调用您的 COM 包装器的程序释放引用(正如 M. Babcock 建议的那样,这将要求程序到达您执行“set pg = Nothing”的步骤),否则您的进度条将无法正确关闭。
我能提出的唯一建议是设置一个“超时”属性(默认为 30 秒)。然后在进度条中使用后台线程,检查最后一次调用“pg.Progess”是在多长时间前进行的,如果它 > 超时值,则关闭。这是假设您可以期望大多数 VB 脚本至少每 X 秒报告一次进度(其中 X 是超时值)。
关于C# COM DLL 阻止 VBA 应用程序退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8904892/