我有一个使用Excel Interop生成Excel电子表格的Winforms应用程序。
当我尝试以这种方式保存工作表时:
_xlBook.SaveAs(filename, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
...它会失败,告诉我,“ System.Runtime.InteropServices.InvalidComObjectException未处理 的HResult = -2146233049 Message =无法使用已与其基础RCW分离的COM对象。“
但这没有多大意义 - 我没有做任何与线程等有关的事情;这是一个非常普通的香草实用程序。代码中引用的唯一其他地方_xlBook是:
1)
private Excel.Workbook _xlBook;
2)
_xlBook = _xlApp.Workbooks.Add(Type.Missing);
3)
_xlSheets = _xlBook.Worksheets;
_xlSheet = (Excel.Worksheet)_xlSheets.Item[1];
4)
_xlBook.Close(false);
Marshal.ReleaseComObject(_xlBook);
从表单的Deactivate事件调用最后一部分_xlBook被处理掉的部分,该事件是:
private void FormMain_Deactivate(object sender, EventArgs e)
{
DeinitializeExcelObjects();
}
问题是(我在所有引用_xlBook的地方放置断点后发现)在调用 _xlBook.SaveAs()之前调用了FormMain_Deactivate(),当调用它时单击“运行”按钮。
一旦我在FormMain_Deactivate()中注释掉对DeinitializeExcelObjects()的调用,并在调用_xlBook.SaveAs()之后立即调用它,它工作正常 - 创建并保存文件时没有任何错误消息。
那么为什么在表单关闭之前调用FormDeactivate呢?如果这是“按照设计”,那么这个事件就会被错误地命名。
答案 0 :(得分:4)
您已将代码放在错误的位置。 :-)似乎你误解了激活和停用的含义(至少就Windows而言)。
每当激活不同的窗口时都会发生停用,并且当您的表单被销毁时,即使该窗口是Windows桌面,其他窗口也必须变为活动状态。 FormDeactivate 可以被多次调用(例如当用户切换到不同的应用程序,甚至是您自己的应用程序中的不同窗口时)。重要的是要注意,这也适用于激活; FormActivate 也可以多次触发。
如果您希望在关闭表单时运行代码,请将其放在 FormClose 事件处理程序中。