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

4

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

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对象释放)发生?
1个回答

2

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

在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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接