當您自動化 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 參考計數。
- 若要釋放給該變數參考,將設定為 Nothing 或 Null 的變數等。
- 使用 Quit 方法的 Office 應用程式物件來告訴伺服器關機。
重現這個問題的步驟
- 啟動 Visual Studio.NET。
- 在 [檔案] 功能表上按一下 [新增],然後按一下 [專案]。在 Visual Basic 專案 下, 選取 [Windows 應用程式],然後按一下 [確定]。預設會建立 Form1。
- 將參考加入至 Microsoft Excel 物件程式庫。要這麼做,請您執行下列步驟:
- 在 [專案] 功能表上按一下 [加入參考]。
- 在 [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 物件程式庫 - 按一下 [[確定] 在 [加入參考] 對話方塊以接受您的選擇。
- 在 [檢視] 功能表上按一下 [工具箱],] 然後將 Button 控制項拖曳至 [Form1]。
- 連按兩下 [Button1]。在表單的 [程式碼] 視窗隨即出現。
- 將下列程式碼加入至 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 不會再出現在 [處理序] 清單。
- 您在 < 解決方案 > 一節中實作步驟時, 後釋放最後一個變數結束 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() 方法嘗試回收可用的最大記憶體。請注意這並不保證回收所有的記憶體。