如何检测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);
}

但是,如果工作簿已经关闭,这会引发错误,那么我如何安全地检查它?如果可能的话,我宁愿不只是捕捉错误,因为这种类型的事情往往会扭曲调试。有没有一种干净的方法可以在关闭之前找到工作簿的状态?

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

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

在Excel中没有像IsOpen这样的属性。您可以尝试参考工作簿:

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

但如果书没有打开,这会产生COM错误,因此会变得非常混乱。

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

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

如果工作簿已保存,则不需要workbook.Close(),这反映了Excel的正常行为。但是,需要释放所有Excel对象引用。正如您所发现的,这有点麻烦,CloseQuit并不能单独实现这一点。


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

相关内容

  • 没有找到相关文章

最新更新