2015-01-13 3 views
8

次のコードは、私のプログラムが終了した後まで、Microsoft Excelのバックグラウンド・プロセスを実行したまま:Microsoft.Office.Interop.Excel.Application.Quit()はバックグラウンドプロセスを実行したままにしているのはなぜですか?

var excelApplication = new Application(); 
var workbooks = excelApplication.Workbooks; 
var workbook = excelApplication.Workbooks.Open(file.FullName); 

workbook.Close(); 
excelApplication.Workbooks.Close(); 
excelApplication.Quit(); 

Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(workbooks); 
Marshal.ReleaseComObject(excelApplication); 

なぜ?私は何が欠けていますか?

+0

「// do stuff」のすべてを削除してみましたか?これの主な理由は、残りの参照、割り当てられたオブジェクトなどです。 – DrKoch

+0

参照してくださいhttp://stackoverflow.com/questions/9962157/safely-disposing-excel-interop-objects-in-c –

+0

私のテストでは、そこに何もコメントがありませんでした。私が投稿したコードは完全な/正確なコードでした。 – skinnysoftware

答えて

16

ありがとうございました!

application.Workbooks!= application.Workbooks

このプロパティは、変数を公開していませんが、それは値を生成します。したがって、私はWorkbooksプロパティにアクセスするたびに新しいCOMオブジェクトを作成します。

コードが修正され、すべて正常です。みなさん、ありがとう。

var excelApplication = new Application(); 
var workbooks = excelApplication.Workbooks; 
var workbook = workbooks.Open(pathToExcelWorkbook); // Fixed 

workbook.Close(); 
workbooks.Close(); 
excelApplication.Quit(); 

Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(workbooks); 
Marshal.ReleaseComObject(excelApplication); 
+0

本当の答えをマークしてください。 –

+2

こんにちは@eugene - あなたの答えは確かに正しい方向に私を導いたが、私はそれが問題全体を解決するのに十分具体的であるとは思わなかった。 2つのコードサンプルで3行目を比較すると、Workbookプロパティが常に新しいオブジェクトを返すことを理解できなかったことがわかります。 – skinnysoftware

5

これは、Officeアプリケーションの広範な問題です。すべてのExcelアドイン/オートメーションアプリケーションは、不要になったときにExcelオブジェクトへの参照を体系的に解放する必要があります。 Excelオブジェクトへの参照を体系的に解放できないと、Microsoft Office Excelが正常にシャットダウンしなくなる可能性があります。詳細については、Systematically Releasing Objectsを参照してください。 Outlookに関連していますが、同じ原則をすべてのOfficeアプリケーションに適用できます。

Excelオブジェクトの使用を終了したら、System.Runtime.InteropServices.Marshal.ReleaseComObjectを使用して解放します。次に、変数をVisual BasicのNothing(C#ではnull)に設定して、オブジェクトへの参照を解放します。

+2

理由がわからない、妥当な応答のようです。 – Kehlan

+0

これは新しいOfficeバージョンのケースですか?投稿したリンクは、2007年の情報へのリンクです。また、ドキュメントのバージョン(「その他のバージョン」のドロップダウン)を変更すると、2010または2013のSystem.Runtime.InteropServices.Marshal.ReleaseComObjectに関する情報はありません。 –

+1

新しいOfficeバージョンにも同じことが適用されます。 –

0

がこの LIKE行うには間違った方法ですが、これは問題修正する最も簡単な方法です:あなたが必要とするすべてはあなたが必要なときにすべて初期化されていない変数を初期化することである

[DllImport("user32.dll")] 
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 

    private Application _excelApp; 
    private Workbook _excelWorkBook; 
    private Worksheet _excelSheet; 

    private void CloseExcelApp() 
    { 
     int hWnd = _excelApp.Application.Hwnd; 
     uint processID; 

     GetWindowThreadProcessId((IntPtr)hWnd, out processID); 
     Process.GetProcessById((int)processID).Kill(); 

     _excelWorkBook = null; 
     _excelApp = null; 
     _excelSheet = null; 
    } 

をそれを処理し、アプリケーションを閉じる必要があるときにCloseExcelApp()を呼び出します。

関連する問題