如何检测Excel工作簿是否已关闭(在C#中使用Interop)?

我正在开发一个C#项目,它使用Microsoft.Office.Interop.Excel.Application从Excel文件中读取值:

try {
    Application xlApp = new Application();
    Workbook workbook = xlApp.Workbooks.Open(filename)
    // ... Load Excel values ...
} finally {
    // ... Tidy up ...
}

在finally块中,我想确保所有内容都已关闭并正确处理,因此内存中没有任何内容,Excel会干净利落地关闭.已经看到了关于这段代码应该是什么样子的各种线程(比我想象的更复杂!)但它可能包含的一件事是:

if (workbook != null) {
    workbook.Close();
    // ... possibly also Marshal.FinalReleaseComObject(workbook);
}

但是,如果工作簿已经关闭,则会引发错误,因此如何安全地检查?如果可能的话,不希望仅仅捕获错误,因为这种类型的东西往往会扭曲调试.在关闭之前有没有找到工作簿状态的干净方法?

还有一个q – 我想知道如果xlApp.Quit();是否需要workbook.Close();之后完成 – 退出Excel应用程序会导致workbook.Close()(以及任何释放的COM对象)隐式发生吗?

最佳答案 在打开工作簿时,最好的建议是跟踪工作簿并在适当时关闭它.如果您的代码非常详细,那么您可以存储一个布尔值,指示文件当前是打开还是关闭.

在Excel中没有像IsOpen这样的属性.您可以尝试引用该工作簿:

Workbook wbTest = xlApp.Workbooks.get_Item("some.xlsx");

但如果书没有打开,这会产生COM错误,所以会变得非常混乱.

相反,创建自己的函数IsOpen,它返回一个布尔值并循环遍历当前打开的工作簿(工作簿集合),检查名称,使用如下代码:

foreach (_Workbook wb in xlApp.Workbooks)
{
    Console.WriteLine(wb.Name);
}

如果已保存工作簿,则不需要workbook.Close() – 反映Excel的正常行为.但是,需要释放所有Excel对象引用.正如你所发现的那样,这有点繁琐,而Close和Quit并不是自己实现的.

    static bool IsOpen(string book)
    {
        foreach (_Workbook wb in xlApp.Workbooks)
        {
            if (wb.Name.Contains(book))
            {
                return true;
            }
        }
        return false;
    }
点赞