徵兆
當您從 Microsoft Microsoft Office .NET Visual Basic Microsoft Visual C# .NET 將應用程式自動化時,Office應用程式不會在您呼叫 Quit 方法時離開。
原因
當 Visual Studio .NET 從受管理程式碼呼叫 COM 物件時,系統會自動在 RCW (建立可) 。 RCW 會封送 .NET 應用程式和 COM 物件之間的呼叫。 RCW 會保留 COM 物件的參照計數。 因此,如果 RCW 上尚未發行所有參照,則 COM 物件不會停止。
解決方案
若要確定應用程式Office,請判斷您的自動化程式碼是否符合下列準則:
-
將每個物件宣告為新變數。 例如,變更下列程式碼:
oBook = oExcel.Workbooks.Add()
變更為下列專案:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()
-
在迴圈中使用 System.Runtime.InteropServices.Marshal.ReleaseComObject,直到您完成使用物件時,它才會返回 0。 System.Runtime.InteropServices.Marshal.ReleaseComObject 會解壓縮 RCW 的參照計數,而迴圈會確保基礎 COM 元件已發行,無論該元件已重新輸入 CLR 多少次。
-
若要放開變數的參照,請設定變數等於無或 Null。
-
使用應用程式物件的 Office 方法,要求伺服器關閉。
狀態
產生此錯誤是系統刻意為之。
其他相關資訊
重現行為的步驟
-
啟動 Visual Studio .NET。
-
在 [檔案> 功能表上,按一下 [新增,然後按一下 [Project。 在 [Visual Basic中,選取 [Windows應用程式,然後按一下 [確定。
注意 表單 1 預設為建立。 -
新增對物件程式庫Microsoft Excel參照。 如果要執行這項操作,請依照下列步驟執行:
-
在 [Project功能表上,按一下 [新增參照。
-
在 [COM> 定位點上,找到 [物件程式庫Excel,然後按一下 [選取。
2002 Microsoft Excel:Microsoft Excel 10.0 物件文件庫Note如果您尚未這麼做,建議您下載並安裝 Microsoft Office XP 主交互操作程式集 (PIAs) 。 若要進一步Office XP PIAs,請前往下列 Microsoft 知識庫文章:328912 Microsoft Office XP 主交互操作程式集 (PIAs) 可供下載 適用于 Microsoft Office Excel 2003:Microsoft Excel 11.0 物件程式庫
-
按一下 [新增參考資料> 對話方塊中的 [確定以接受您的選取範圍。
-
-
在 [視圖> 功能表上,按一下 [工具箱,然後將按鈕控制項拖曳到表單 1。
-
按兩下按鈕1。
注意表單的代碼視窗會出現。 -
在 Form1.vb 頂端新增下列程式碼:
Imports Microsoft.Office.Interop
-
在程式碼視窗中取代下列程式碼:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click End Sub
取代下列程式碼:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim oApp As New Excel.Application() Dim oBook As Excel.Workbook = oApp.Workbooks.Add Dim oSheet As Excel.Worksheet = oApp.ActiveSheet oSheet = Nothing oBook.Close(False) oBook = Nothing oApp.Quit() oApp = Nothing Debug.WriteLine("Sleeping...") System.Threading.Thread.Sleep(5000) Debug.WriteLine("End Excel") End Sub
-
按下 F5 以執行此應用程式。
-
開啟Windows管理員。 在 Visual Studio中,顯示輸出視窗以查看調試訊息。 按一下命令按鈕。 請注意,Excel.exe程式清單中會出現一個名稱實例。
-
即使應用程式Excel,Excel實例仍在工作清單中執行。 關閉對話方塊,並Excel程式清單中不再顯示該對話方塊。
-
當您執行「解決」區段的步驟時,Office釋放最後一個變數後,應用程式即會退出。 使用下列程式碼取代步驟 5 中的函數:
Private Sub NAR(ByVal o As Object) Try While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) End While Catch Finally o = Nothing End Try End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim oApp As New Excel.Application() Dim oBooks As Excel.Workbooks = oApp.Workbooks Dim oBook As Excel.Workbook = oBooks.Add Dim oSheet As Excel.Worksheet = oApp.ActiveSheet NAR(oSheet) oBook.Close(False) NAR(oBook) NAR(oBooks) oApp.Quit() NAR(oApp) Debug.WriteLine("Sleeping...") System.Threading.Thread.Sleep(5000) Debug.WriteLine("End Excel") End Sub
如果您使用的是 Visual C# .NET,請參照 NAR () 函數的代碼:
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch {}
finally
{
o = null;
}
}
注意 從 .NET Framework 2.0 開始,您可以使用 System.Runtime.InteropServices.Marshal.FinalReleaseComObject,而非 while 迴圈呼叫 System.Runtime.InteropServices.Marshal.ReleaseComObject,以取得相同的結果。
疑難排解
注意 如果您遵循「重現行為的步驟」一節中所述的步驟,而且伺服器仍未關閉,您可以使用 GC。收集 () 方法與 GC。釋放最後一個物件之後,WaitForPendingFinalizers () 方法。 因為執行時間會執行 RCW 上的垃圾收集,因此 GC。收集 () 方法會強制執行垃圾收集器,並可能會釋出 RCW 仍具有的任何參照。 GC。收集 () 方法會嘗試回收可用的最大記憶體。 請注意,這不保證會回收所有記憶體。
適用於
本文也適用于:
-
Microsoft Visual Basic .NET (所有版本)
-
Microsoft Visual C# .NET (所有版本)
-
Microsoft Office 2016 (所有版本)
-
Microsoft Office 2013 (所有版本)