C#COM DLL阻止VBA应用程序退出

C#COM DLL阻止VBA应用程序退出,c#,multithreading,vba,com,C#,Multithreading,Vba,Com,我创建了一个C#COM DLL,它本质上是一个增强的进度条,在一个新线程上运行System.Windows.Forms.Application.Run(),以显示带有对话框的表单。要在使用VBA的第三方应用程序中使用它,请执行以下操作: Set pg = CreateObject("MyNS.MyProgressBar") pg.ShowBar() . . pg.Progress = 0.5 . . pg.ShutDownBar() 问题在于,用户能够在到达pg.ShutDownBar()之前

我创建了一个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建议的那样,这将要求程序进入一个执行“设置pg=Nothing”的步骤),否则您的进度条将无法正常关闭


我唯一的建议是设置一个“timeout”属性(默认为30秒)。然后在进度条中使用一个后台线程,检查上次调用“pg.proges”的时间,如果是>超时值,则关闭。这是假设您可以期望大多数VB脚本至少每X秒报告一次进度(其中X是超时值)。

这是COM引用计数工作方式的问题。除非调用COM包装器的程序释放引用(正如M.Babcock建议的那样,这将要求程序进入一个执行“设置pg=Nothing”的步骤),否则您的进度条将无法正常关闭


我唯一的建议是设置一个“timeout”属性(默认为30秒)。然后在进度条中使用一个后台线程,检查上次调用“pg.proges”的时间,如果是>超时值,则关闭。这是假设您可以期望大多数VB脚本至少每X秒报告一次进度(其中X是超时值)。

听起来像是典型的DoEvents()问题。不要使用它。没有任何代码调用DoEvents()。。。我尝试不使用Application.Run在单独的线程上启动对话框,而是在单独的线程上使用form.ShowDialog(),但是对话框基本上被冻结了。。。不知道为什么?如果在应用程序退出事件中将进度条对象设置为
Nothing
,会发生什么?听起来像是典型的DoEvents()问题。不要使用它。没有任何代码调用DoEvents()。。。我尝试不使用Application.Run在单独的线程上启动对话框,而是在单独的线程上使用form.ShowDialog(),但是对话框基本上被冻结了。。。不知道为什么?如果在应用程序退出事件中将进度条对象设置为
Nothing
,会发生什么?是!这很有效。。。我将窗口句柄发送到新线程,然后每隔几秒钟检查一次窗口句柄是否仍然有效。如果不是,它就会关闭。谢谢对这很有效。。。我将窗口句柄发送到新线程,然后每隔几秒钟检查一次窗口句柄是否仍然有效。如果不是,它就会关闭。谢谢