我在C#和Office 2013中使用Visual Studio 2015社区。 p>
以下代码用于打开和关闭Excel。然后我添加了代码来打开一个特定的工作表,如下面的例2所示。而且,这很有效,Excel正确关闭。
然后我移动了一些东西,但忘了使用ReleaseComObject
作为工作表并且Excel保持打开状态,所以我在任务管理器中手动关闭它。
现在,以下示例中的任何一个都无效。在我意外忘记释放COM对象后,Excel永远不会关闭,除非我重启我的机器。
示例1
private bool loadExcel()
{
// Open Excel
Excel.Application myApp = new Excel.Application();
// Hide Excel
myApp.Visible = false;
GSIWorkbook = myApp.Workbooks.Open( "D:\\Test.xlsx" );
// Cleanup
GSIWorkbook.Close( false );
// Manual disposal because of COM
while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( GSIWorkbook ) != 0 )
{ }
myApp.Application.Quit();
myApp.Quit();
while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( myApp ) != 0 )
{ }
myApp = null;
GSIWorkbook = null;
GC.Collect();
GC.WaitForPendingFinalizers();
return true;
} // End loadExcel
示例2
private bool loadExcel()
{
// Open Excel
Excel.Application myApp = new Excel.Application();
// Hide Excel
myApp.Visible = false;
GSIWorkbook = myApp.Workbooks.Open( "D:\\Test.xlsx" );
for ( int counter = 1; counter < 100; counter++ )
{
try
{
GSIWorksheet = GSIWorkbook.Sheets[counter];
if ( GSIWorksheet.Name == _gsi2Sheet )
break;
}
catch
{
continue;
}
}
while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( GSIWorksheet ) != 0 )
{ }
// Cleanup
GSIWorkbook.Close( false );
// Manual disposal because of COM
while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( GSIWorkbook ) != 0 )
{ }
myApp.Application.Quit();
myApp.Quit();
while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( myApp ) != 0 )
{ }
myApp = null;
GSIWorkbook = null;
GC.Collect();
GC.WaitForPendingFinalizers();
return true;
} // End loadExcel
答案 0 :(得分:3)
如果您向我们展示了您对excel对象的完整用法,我打赌您会发现您违反了2点规则。听起来很荒谬我知道,但我认为你无意中创建了无法通过Excel或GC处理的对象实例,然后它无法正常关闭。 (称为Runtime Callable Wrappers)
当你使用 - 比如说 - 这段代码:
xlWorkBook = xlApp.Workbooks.Add
......你实际上是在造成这个问题。您需要创建一个指向Workbooks
的变量并直接使用它并将其丢弃。
链接示例:
Dim xlApp As New Excel.Application
Dim xlWorkBooks As Excel.Workbooks = xlApp.Workbooks
Dim xlWorkBook As Excel.Workbook = xlWorkBooks.Add()
....所有代码,然后
xlApp.Quit()
If Not xlWorkBook Is Nothing Then
Marshal.FinalReleaseComObject (xlWorkBook)
xlWorkBook = Nothing
End If
If Not xlWorkBooks Is Nothing Then
Marshal.FinalReleaseComObject (xlWorkBooks)
xlWorkBooks = Nothing
End If
If Not xlApp Is Nothing Then
Marshal.FinalReleaseComObject (xlApp)
xlApp = Nothing
End If
xlApp.Quit()
详情请见此处:
http://www.siddharthrout.com/2012/08/06/vb-net-two-dot-rule-when-working-with-office-applications-2/