文章編號: 317109 - 上次校閱: 2004年9月3日 - 版次: 4.2

Office 應用程式不會結束之後從 Visual Studio.NET 用戶端的自動化

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

徵狀

當您自動化 Microsoft Office 應用程式,從 Microsoft Visual Basic.NET 或 Microsoft Visual C#.NET 時,Office 應用程式不會不會結束,當您呼叫 Quit 方法。

發生的原因

Visual Studio.NET 呼叫 COM 物件從 Managed 程式碼時, 它會自動建立一個執行階段可呼叫包裝函式 (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。這個減量之 RCW 參考計數。
  • 若要釋放給該變數參考,將設定為 NothingNull 的變數等。
  • 使用 Quit 方法的 Office 應用程式物件來告訴伺服器關機。

狀況說明

這種行為是經過設計規劃的。

其他相關資訊

重現這個問題的步驟

  1. 啟動 Visual Studio.NET。
  2. 在 [檔案] 功能表上按一下 [新增],然後按一下 [專案]。在 Visual Basic 專案 下, 選取 [Windows 應用程式],然後按一下 [確定]。預設會建立 Form1。
  3. 將參考加入至 Microsoft Excel 物件程式庫。要這麼做,請您執行下列步驟:
    1. 在 [專案] 功能表上按一下 [加入參考]。
    2. 在 [COM] 索引標籤上,Excel,尋找物件程式庫,然後按一下 [選取]。

      如 Microsoft Excel 2002: Microsoft Excel 10.0 物件程式庫

      附註如果您已經不這樣,建議您下載並安裝組 [Microsoft Office XP 主要 Interop 件 (PIA)。 取得更多資訊有關 Office XP PIA 按一下 [下面的文件編號,檢視 「 Microsoft 知識庫 」 中的發行項]:
      328912? (http://support.microsoft.com/kb/328912/ ) Microsoft Office XP 主要 Interop 組件 (PIA) 是可供下載
      對於 Microsoft Office Excel 2003: Microsoft Excel 11.0 物件程式庫
    3. 按一下 [[確定] 在 [加入參考] 對話方塊以接受您的選擇。
  4. 在 [檢視] 功能表上按一下 [工具箱],] 然後將 Button 控制項拖曳至 [Form1]。
  5. 連按兩下 [Button1]。在表單的 [程式碼] 視窗隨即出現。
  6. 將下列程式碼加入至 Form1.vb 的頂端:
    Imports Microsoft.Office.Interop
    					
  7. 取代下列程式碼在程式碼視窗
        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
    					
  8. 按下 F5 以執行應用程式。
  9. 開啟 [Windows 工作管理員]。在 Visual Studio 顯示輸出視窗,以查看偵錯訊息。按一下指令按鈕,然後請注意 Excel.exe 的執行個體就會顯示 [處理序] 清單中。
  10. 即使在應用程式已完成沈睡之後,Excel 的執行個體仍工作清單中執行。關閉此對話方塊,並請注意 Excel 不會再出現在 [處理序] 清單。
  11. 您在 < 解決方案 > 一節中實作步驟時, 後釋放最後一個變數結束 Office 應用程式。使用下列程式碼取代步驟 5 中的函式:
      Private Sub NAR(ByVal o As Object)
        Try
          System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
        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 
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
    }
    catch {}
    finally 
    {
        o = null;
    }
}

疑難排解

請注意是否您依照 < 步驟來重現 [>] 區段中所述的步驟執行,而且伺服器仍無法順利關機您可以使用 GC.Collect() 方法和 GC.WaitForPendingFinalizers() 方法後釋放最後一個物件。因為執行階段會對 RCW 執行記憶體回收,GC.Collect() 方法會強制記憶體回收行程在執行,並可能會釋放之 RCW 仍有任何參考。GC.Collect() 方法嘗試回收可用的最大記憶體。請注意這並不保證回收所有的記憶體。

這篇文章中的資訊適用於:
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual C# .NET 2003 標準版
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
關鍵字:?
kbmt kbautomation kbprb KB317109 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:317109? (http://support.microsoft.com/kb/317109/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。