相关疑难解决方法(0)

使用Wrapper对象正确清理excel互操作对象

所有这些问题:

解决了C#在使用后没有正确释放Excel COM对象的问题.解决这个问题主要有两个方向:

  1. 不再使用Excel时终止Excel进程.
  2. 注意首先明确地将用于变量的每个COM对象分配,并保证最终在每个上执行Marshal.ReleaseComObject.

有人说过2太繁琐了,你是否忘记在代码中的某些地方忘记遵守这条规则总是存在一些不确定性.仍然1对我来说似乎很脏并且容易出错,我想在有限的环境中试图杀死一个进程可能会引发安全错误.

所以我一直在考虑通过创建另一个模仿Excel对象模型的代理对象模型来解决问题2(对我来说,实现我实际需要的对象就足够了).原则如下:

  • 每个Excel Interop类都有其代理,用于包装该类的对象.
  • 代理在其终结器中释放COM对象.
  • 代理模仿Interop类的接口.
  • 最初返回COM对象的任何方法都会更改为返回代理.其他方法只是将实现委托给内部COM对象.

例:

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)

我特别向你提问:

  • 谁发现这是一个坏主意,为什么?
  • 谁发现这是一个可怕的想法?如果是这样,为什么没有人实施/发布这样的模型呢?是仅仅是因为努力,还是我错过了这个想法的杀戮问题?
  • 在终结器中执行ReleaseCOMObject是不可能/不好/容易出错的吗?(我只看到过将它放在Dispose()而不是终结器中的建议 - 为什么?)
  • 如果方法有意义,有什么建议可以改进吗?

c# excel interop com-interop

11
推荐指数
1
解决办法
4479
查看次数

防止Excel退出

我错过了一个Excel.Application.Quit或一个Excel.Application.BeforeQuit事件.有人知道模仿这些事件的解决方法吗?

我通过COM Interop从C#WinForms应用程序访问Excel.给定一个Excel.Application对象,我该怎么做:

  1. 最好是防止Excel退出?
  2. 如果这不可能,我怎么能至少注意到 Excel退出的时候?

请注意:由于我有一个COM引用Excel.Application,当Excel被用户"退出"时,Excel进程不会退出.虽然这听起来很矛盾,但事实就是如此.通过"退出"我的意思是用户点击窗口右上角的"退出"或"十字按钮".窗口关闭,文件被卸载,加载项被卸载以及Excel除了我没有任何线索之外做的任何东西.但是我仍然可以使用该Application对象来"恢复"该过程并使Excel再次可见,尽管这些加载项随后丢失,而且我还不知道还有什么处于未定义状态.

为了摆脱这个问题,我想在一开始就取消退出(想想BeforeQuit Cancel = true它是否存在),或者至少在退出Excel时得到通知,这样我就可以释放COM对象并使流程真正退出,下次我再次需要Excel时,我会知道我需要先启动它.

不幸的是,它是一个恶性循环:只要Excel运行,我需要COM对象.因此, Excel退出之前,我无法处理它们.另一方面,只要COM对象存在,即使Excel假装退出,进程也不会退出,因此我不能等待进程退出事件或类似事件.

我有一种令人不快的感觉,就是我要把头撞在砖墙上......

c# com excel interop excel-2007

11
推荐指数
2
解决办法
2679
查看次数

标签 统计

c# ×2

excel ×2

interop ×2

com ×1

com-interop ×1

excel-2007 ×1