所有这些问题:
解决了C#在使用后没有正确释放Excel COM对象的问题.解决这个问题主要有两个方向:
有人说过2太繁琐了,你是否忘记在代码中的某些地方忘记遵守这条规则总是存在一些不确定性.仍然1对我来说似乎很脏并且容易出错,我想在有限的环境中试图杀死一个进程可能会引发安全错误.
所以我一直在考虑通过创建另一个模仿Excel对象模型的代理对象模型来解决问题2(对我来说,实现我实际需要的对象就足够了).原则如下:
例:
public class Application
{
private Microsoft.Office.Interop.Excel.Application innerApplication
= new Microsoft.Office.Interop.Excel.Application innerApplication();
~Application()
{
Marshal.ReleaseCOMObject(innerApplication);
innerApplication = null;
}
public Workbooks Workbooks
{
get { return new Workbooks(innerApplication.Workbooks); }
}
}
public class Workbooks
{
private Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks;
Workbooks(Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks)
{
this.innerWorkbooks = innerWorkbooks;
}
~Workbooks()
{
Marshal.ReleaseCOMObject(innerWorkbooks);
innerWorkbooks = null;
}
}
Run Code Online (Sandbox Code Playgroud)
我特别向你提问:
我错过了一个Excel.Application.Quit或一个Excel.Application.BeforeQuit事件.有人知道模仿这些事件的解决方法吗?
我通过COM Interop从C#WinForms应用程序访问Excel.给定一个Excel.Application对象,我该怎么做:
请注意:由于我有一个COM引用Excel.Application,当Excel被用户"退出"时,Excel进程不会退出.虽然这听起来很矛盾,但事实就是如此.通过"退出"我的意思是用户点击窗口右上角的"退出"或"十字按钮".窗口关闭,文件被卸载,加载项被卸载以及Excel除了我没有任何线索之外做的任何东西.但是我仍然可以使用该Application对象来"恢复"该过程并使Excel再次可见,尽管这些加载项随后丢失,而且我还不知道还有什么处于未定义状态.
为了摆脱这个问题,我想在一开始就取消退出(想想BeforeQuit Cancel = true它是否存在),或者至少在退出Excel时得到通知,这样我就可以释放COM对象并使流程真正退出,下次我再次需要Excel时,我会知道我需要先启动它.
不幸的是,它是一个恶性循环:只要Excel运行,我需要COM对象.因此,在 Excel退出之前,我无法处理它们.另一方面,只要COM对象存在,即使Excel假装退出,进程也不会退出,因此我不能等待进程退出事件或类似事件.
我有一种令人不快的感觉,就是我要把头撞在砖墙上......