外部关闭excel进程时的错误处理

时间:2016-05-05 13:25:32

标签: c# excel

我正在编写一个与excel交互的程序。关于在通过任务管理器杀死excel时关闭我的应用程序,我遇到了一些问题。

当我的程序启动时,它会设置Excel.Application ObjApp = new Excel.Application();

关闭时,以

结束
if (ObjApp != null)
{
    ObjApp = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
ObjApp.Quit();

Environment.Exit(0);

但是,如果通过任务管理器杀死excel并退出,我会得到这个

  

" NullReferenceException未被用户代码"处理在ObjApp.Quit();

基本上我需要弄清楚的是怎么说

  

"如果ObjApp(我的Excel实例)仍然可用,请退出,否则不要。"   我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

你不应该担心你无法控制的事情。用户决定终止程序正在使用的 Excel 应用程序是不是你应该试图找出的东西(没有安全的方法来确定是否是这种情况,你可以总是以竞争条件结束,但不要让我们陷入困境。)

那你该怎么办?实现代码,处理应用程序可以处理的任何合理的故障情况。失败的原因究竟是什么并不重要,它可以是任何东西:它可能是用户关闭应用程序,但它也可能是一些模糊的 Excel 错误导致应用程序崩溃, OS 打嗝,硬件故障,你有什么。

你是怎么做到的?好吧,使用exception handling

try
{
     //Normal code path goes here. Assume appObj is running;
     ObjApp.Quit();
}
//optional catch clauses here
finally
{
    //Safe clean up you want running in normal execution or any managable
    //scenario. By safe I mean you shouldn't be handling/saving/modifying
    //any sensitive data, you should just clean up your COM objects.
    //Anything potentially unsafe should be handled in specific catch
    //clauses where you know the nature of the exception and you can take
    //specific measures to recover or shut down safely.

    //In some unrecoverable scenarios this might not even run.
    Marshal.FinalReleaseComObject(ObjApp);
}

您可以为特定的异常类型添加catch子句以用于登录,或者通知用户发生了意外情况;我认为COMException是一个很好的选择,任何其他异常都应该传递给调用堆栈,并让其他知道更好的人处理它。

答案 1 :(得分:0)

首先

GC.WaitForPendingFinalizers()将为objects运行析构函数。

对于ObjApp == null时的示例,GC可以解析对象ObjApp。然后ObjApp将为null。

ObjApp.Quit()必须通过电话befeore GC.WaitForPendingFinalizers()

第二次您将ObjApp设置为null值,之后调用ObjApp.Quit()。如果Quit()方法是非静态的,那么程序抛出NullReferenceException并且是预期的。

试试这个:

ObjApp.Quit();

if (ObjApp != null)
{
    ObjApp = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();

Environment.Exit(0);

当我关闭Excel文件时,我这样做:

            ...//

            this.workbook.Close();
            this.application.Workbooks.Close();
            this.application.Quit();
        }
        finally
        {
            Marshal.FinalReleaseComObject(this.autoFitRange);
            GC.Collect();
            Marshal.ReleaseComObject(this.numberFormatRange);
            GC.Collect();
            Marshal.ReleaseComObject(this.range);
            GC.Collect();
            Marshal.ReleaseComObject(this.workbook);
            GC.Collect();
            Marshal.ReleaseComObject(this.sheet);
            GC.Collect();
            Marshal.ReleaseComObject(this.workbooks);
            GC.Collect();
            Marshal.ReleaseComObject(this.application);
            GC.Collect();

正如您所看到的,我在使用ReleaseComObject excel libary期间为我创建的所有对象运行COM。如果我这样做,我就会成功关闭Excel,并且该过程将从任务管理器中消失。

这可以帮助你。