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

文章翻譯 文章翻譯
文章編號: 317109 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

徵狀

當您將自動化 Microsoft Office 應用程式,在Microsoft Visual Basic 的.net Microsoft Visual C# 時,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 應用程式物件,以告知伺服器的方法關閉。

狀況說明

這行為是經過設計規劃。

其他相關資訊

如果要重現這個問題的步驟

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

      Excel 2002: Microsoft Excel 10.0 物件程式庫

      附註如果您尚未如此做,則建議您下載並安裝 Microsoft Office XP 主要 Interop 組件 (Pia)。 如需其他有關 Office XP Pia 的詳細資訊,請按一下下面的文件編號,檢視 「 Microsoft 知識庫 」 中的文件:
      328912Microsoft Office XP 主要 interop 組件 (Pia) 有可供下載
      Microsoft Office,現在要學習如何: Microsoft Excel 11.0 物件程式庫
    3. 按一下[確定]在 [加入參考] 對話方塊中,表示接受選擇。
  4. 在 [檢視] 功能表中,按一下 [工具箱],然後拖曳到 Form1 的 [ Button ] 控制項。
  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
          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
    					
如果您正在使用視覺化 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。Collect()方法,並GC。WaitForPendingFinalizers()之後發行的最後一個物件的方法。因為執行階段會對 RCW, GC 執行記憶體回收。Collect()方法會強制執行記憶體回收行程,並可能會釋放任何RCW 還未關閉的參考。GC。Collect()方法嘗試回收可用的記憶體最大值。請注意,這不保證會回收所有記憶體。

屬性

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

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com