2009-12-15 49 views
7

任何想法爲什麼下面的代碼不會退出通過COM互操作創建的Outlook 2007進程?使用WordC#Outlook 2007 COM互操作應用程序不會退出!

Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application(); 

var item = app.Session.OpenSharedItem("C:\\test.msg") as Microsoft.Office.Interop.Outlook.MailItem; 
string body = item.HTMLBody; 
int att = item.Attachments.Count; 

(item as Microsoft.Office.Interop.Outlook._MailItem).Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard); 
System.Runtime.InteropServices.Marshal.ReleaseComObject(item); 

(app as Microsoft.Office.Interop.Outlook._Application).Quit(); 
System.Runtime.InteropServices.Marshal.ReleaseComObject(app); 
System.Diagnostics.Debugger.Break(); 

幾乎相同片段的作品,所以我不知道如果我忘了收拾東西...

回答

10

你在你的代碼中引用的第三個COM對象:app.Session。這也必須正確釋放。試試這個代碼:

Microsoft.Office.Interop.Outlook.Application app = null; 
Microsoft.Office.Interop.Outlook.NameSpace session = null; 
Microsoft.Office.Interop.Outlook.MailItem item = null; 

try { 
    app = new Microsoft.Office.Interop.Outlook.Application(); 
    session = app.Session; 
    item = session.OpenSharedItem("C:\\test.msg") as Microsoft.Office.Interop.Outlook.MailItem; 

    string body = item.HTMLBody; 
    int att = item.Attachments.Count; 

    (item as Microsoft.Office.Interop.Outlook._MailItem).Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard); 

    (app as Microsoft.Office.Interop.Outlook._Application).Quit(); 
} finally { 
    if(item != null) { 
     System.Runtime.InteropServices.Marshal.FinalReleaseComObject(item); 
    } 
    if(session != null) { 
     System.Runtime.InteropServices.Marshal.FinalReleaseComObject(session); 
    } 
    if(app != null) { 
     System.Runtime.InteropServices.Marshal.FinalReleaseComObject(app); 
    } 
} 
+0

工作。 Session是一個NameSpace對象。謝謝:) – Nikolaos 2009-12-15 14:24:02

+0

沒問題。我已在代碼中替換了該類名稱。 – 2009-12-15 16:41:59

0

嘗試app.Quit繼();

// ReleaseComObject(xApp); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
+0

仍然留戀那裏......還是要謝謝你。 – Nikolaos 2009-12-15 13:33:56

+2

錯誤的方法。 Collect()必須是第一個。 – 2009-12-15 13:41:26

+0

@nobugz:同樣的結果。 Quit()之後仍然存在。 – Nikolaos 2009-12-15 13:47:13

0

試試這個,它爲我工作,會有幾秒鐘的延遲它去之前:

app.Quit(); // 
System.Runtime.InteropServices.Marshal.ReleaseComObject(app); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
2

我不知道辦公室COM互操作性展示的細節,但這裏的一些代碼從MSDN article建議。它表明雙重收集/等待和清除指針有助於RCW包裝器清理。

item = null; 
app.Quit(); 
app = null; 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

該URL但也表明

​​

,我會親自強烈反對,如果你能幫助它,因爲你已經基本上只是摧毀RCW爲您的AppDomain(如文章指出)。

[編輯:同樣的淨垃圾收集器的行爲非常不同的,當一個調試器VS發行代碼裏面,所以測試此調試器之外是非常重要]

+2

+1用於雙重收集建議和調試警告。 – Nikolaos 2009-12-15 14:25:52