C#:closuresExcel窗口closures事件

我的情况是,我正在开发一个启动Microsoft Office Excel应用程序实例的C#应用​​程序。
我更改了某些表单的函数,以便在closures窗体时,实例化的Excel应用程序正在被杀死并从内存中清除。

我想要做的是做相反的事情。 我希望我的Excel实例在退出时closures我的窗体窗体。

好吧,我甚至没有试过这个,所以我不知道它是否会起作用,但你可以尝试一下这些方法:

Microsoft.Office.Interop.Excel.Application excel = ...; System.Diagnostics.Process excelProcess = null; var processes = System.Diagnostics.Process.GetProcesses(); foreach (var process in processes) { if (process.Handle.ToInt32() == excel.Hwnd) excelProcess = process; } excelProcess.Exited += new EventHandler(excelProcess_Exited); 

UPDATE

尝试下面的代码(它不漂亮):

 Microsoft.Office.Interop.Excel.Application xlsApp; Process xlsProcess; Timer timer; public Form1() { xlsApp = new Microsoft.Office.Interop.Excel.Application(); xlsApp.Visible = true; foreach (var p in Process.GetProcesses()) //Get the relevant Excel process. { if (p.MainWindowHandle == new IntPtr(xlsApp.Hwnd)) { xlsProcess = p; break; } } if (xlsProcess != null) { timer = new Timer(); timer.Interval = 500; timer.Tick += new EventHandler(timer_Tick); timer.Start(); } } void timer_Tick(object sender, EventArgs e) { if (xlsApp != null && !xlsApp.Visible) { //Clean up to make sure the background Excel process is terminated. xlsApp.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsApp); xlsApp = null; } if (xlsProcess.HasExited) { //The event is not fired but the property is eventually set once the process is terminated this.timer.Dispose(); this.Close(); } } 

使用Excel应用程序时的问题是,即使用户closures它的主窗口,该进程仍将继续在后台运行。 为了完全释放它,你必须调用Application.Quit但是只有当你检测到用户正在closures窗口时,你才应该这样做,这正是你正在试图解决的问题…你在这里有一个循环引用:D

locking到相关的System.Diagnostics.Process似乎也不工作,因为Exited事件不会被触发(即使您从任务pipe理器终止后台进程)。 我的猜测是,这个事件只能通过process = Process.Start(...)启动的process = Process.Start(...)触发。

所以我能看到的唯一的解决办法是轮询Excel的主窗口是否可见。 一旦不是,这可能意味着用户closures了主窗口,并且Excel应用程序应该被终止(如果在某些情况下,Excel的主窗口的可见性可能是错误的,而不是当用户想要终止该过程时,则该解决scheme不是有效)。 从那里它是相当简单的。

这是我为同样的情况做的。

我在课堂上创build了一个stream程

 System.Diagnostics.Process myProcess = new System.Diagnostics.Process(); 

然后是closures应用程序的方法的委托

 delegate void KillProcess(); KillProcess aKillProcess; 

将代理设置为应用程序closures方法

 aKillProcess = CloseApp; 

这下面的代码写在button点击事件这打开Excel。 这里订阅stream程的Exited事件

 myProcess.StartInfo = new System.Diagnostics.ProcessStartInfo (@"D:\SomeExcel.xlsx"); myProcess.Start(); myProcess.EnableRaisingEvents = true; myProcess.Exited += new EventHandler(ProcessKilled); 

点击excel的closuresbutton,这个方法会被调用

 private void ProcessKilled(object sender, EventArgs e) { if (this.InvokeRequired) this.Invoke(aKillProcess); else this.Close(); } void CloseApp() { this.Close(); } 

这将closures应用程序。

希望这可以帮助

你的第一次尝试是有效的,只是需要为这个过程提高事件的速度,这就是我为了赶上已经启动的visio退出或崩溃所做的事情。

  foreach (var process in processes) { try { if (process.MainWindowHandle == new IntPtr(app.WindowHandle32)) visioProcess = process; } catch { } } visioProcess.EnableRaisingEvents = true; visioProcess.Exited += new EventHandler(visioProcess_Exited);