C#:在excel关闭事件中关闭windows窗体

本文关键字:windows 窗体 事件 excel | 更新日期: 2023-09-27 18:20:33

我的情况是,我正在开发一个C#应用程序,该应用程序正在启动Microsoft Office Excel应用程序的实例
我更改了Form的一些函数,这样当我的Form关闭时,实例化的Excel应用程序就会被杀死并从内存中清除。

我想做的是反其道而行之。我希望我的Excel实例在退出时关闭我的windows窗体。

C#:在excel关闭事件中关闭windows窗体

好吧,我甚至还没有尝试过,所以我不确定它是否有效,但你可以尝试一下:

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);

更新

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

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应用程序时的问题是,即使用户关闭了它的主窗口,该进程也将继续在后台运行。为了完全释放它,你必须调用Application.Quit,但只有当你检测到用户正在关闭窗口时才应该这样做,这正是你试图解决的问题。。。这里有一个循环参考:D

锁定到相关的System.Diagnostics.Process似乎也不起作用,因为Exited事件永远不会被触发(即使您从任务管理器终止后台进程也不会)。我的猜测是,只有通过process = Process.Start(...)启动的进程才会触发此事件。

因此,我能看到的唯一解决方案是轮询Excel的主窗口是否可见。一旦不是,这可能意味着用户关闭了主窗口,Excel应用程序应该终止(如果在某些情况下,Excel的主窗口的可见性可能是错误的,而不是当用户想要终止流程时,则此解决方案无效)。从那以后,一切都很简单。

这是我对相同场景所做的。

我在类中创建了一个流程

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

然后委托关闭应用程序的方法

delegate void KillProcess();
KillProcess aKillProcess;

将委托设置为应用程序关闭方法

aKillProcess = CloseApp;

下面的代码写在按钮点击事件中这将打开excel。在这里订阅进程的退出事件

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

单击excel的关闭按钮,这种方法将被称为

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

这将关闭应用程序。

希望这能帮助

您的第一次尝试会成功,只需要为流程引发事件,这就是我为捕捉启动的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);