c# – Excel自动化:关闭事件丢失

另外你好,

我正在通过C#中的Interop进行Excel自动化,我希望在工作簿关闭时得到通知.但是,工作簿上没有Close事件,也没有应用程序上的Quit事件.

以前有人这样做过吗?如何编写一段代码来响应正在关闭的工作簿(只有在工作簿真正关闭时才会执行)?理想情况下,这应该在关闭工作簿后发生,因此我可以依赖该文件来反映所有更改.

到目前为止我发现的细节:

一个BeforeClose()事件,但是如果有未保存的更改,则在询问用户是否保存它们之前引发此事件,所以目前我可以处理该事件,我没有最终文件而且我无法发布COM对象,这两件事我都需要/做.我甚至不知道工作簿是否会实际关闭,因为用户可能会选择中止关闭.

然后有一个BeforeSave()事件.因此,如果用户选择“是”来保存未保存的更改,则在BeforeClose()之后执行BeforeSave().但是,如果用户选择“中止”,然后点击“文件 – >保存”,则执行完全相同的事件顺序.此外,如果用户选择“否”,则根本不执行BeforeSave().只要用户没有单击任何这些选项,同样适用.

解决方法

我使用类似轮询的方法创建了一个hack,它可以工作:

鉴于要观察的工作簿,我创建了一个线程,它定期尝试在工作簿集合中查找该工作簿.

(disposableCom类是我目前的properly cleanup COM objects解决方案.)

Excel.Application app = wbWorkbook.Application;
string sWorkbookName = wbWorkbook.Name;

Thread overseeWorkbooksThread = new Thread(new ThreadStart(
    delegate()
    {
        bool bOpened = false;

        Excel.Workbooks wbsWorkbooks = app.Workbooks;
        using (new disposableCom<Excel.Workbooks>(wbsWorkbooks))
        {
            while (true)
            {
                Thread.Sleep(1000);

                if (wbsWorkbooks.ContainsWorkbookProperly(sWorkbookName))
                    bOpened = true;
                else
                    if (bOpened)
                        // Workbook was open,so it has been closed.
                        break;
                    else
                    {
                        // Workbook simply not finished opening,do nothing
                    }
            }

            // Workbook closed
            RunTheCodetoBeRunAfterWorkbookIsClosed();
        }
    }));

overseeWorkbooksThread.Start();

“ContainsWorkbookProperly”扩展方法如下所示:

public static bool ContainsWorkbookProperly(this Excel.Workbooks excelWbs,string sWorkbookName)
{
    Excel.Workbook wbTemp = null;
    try
        wbTemp = excelWbs.Item(sWorkbookName);
    catch (Exception)
    {
        // ignore
    }

    if (wbTemp != null)
    {
        new disposableCom<Excel.Workbook>(wbTemp).dispose();
        return true;
    }

    return false;
}

如果有更简单或更好的解决方案,我仍然会感兴趣.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...