2014-02-25 56 views
0

我有這個代碼,我訪問Outlook資源管理器來獲取選定的項目。我第一次訪問它時會返回一封電子郵件,現在如果我轉到outlook並選擇較舊的電子郵件,它將返回兩封電子郵件,而不是隻有一封。如果我進一步選擇新的項目(不是多選簡單的單選),他們就開始疊加起來。Outlook interoop。 o選擇幾次嘗試後開始返回舊的選擇項目

代碼在這裏:

public IEnumerable<MailItemVM> GetSelectedMailItem() 
     { 
      RetrieveOutlookProcessHandle(false); 

      List<MailItemVM> result = new List<MailItemVM>(); 

      //olApp = new Microsoft.Office.Interop.Outlook.Application(); 
      //KillOlProcess = true; 

      Microsoft.Office.Interop.Outlook.Explorer oExplorer = olApp.ActiveExplorer(); 
      Microsoft.Office.Interop.Outlook.Selection oSelection = oExplorer.Selection; 

      foreach (object item in oSelection) 
      { 
       Microsoft.Office.Interop.Outlook.MailItem mi = (Microsoft.Office.Interop.Outlook.MailItem)item; 

       if (mi != null) 
       { 
        MailItemVM mVM = new MailItemVM() 
        { 
         Title = mi.Subject, 
         Description = mi.BodyFormat == Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML ? mi.HTMLBody : mi.Body 
        }; 
        result.Add(mVM); 
       } 
       break; 

      } 

      System.Runtime.InteropServices.Marshal.FinalReleaseComObject(olApp); 
      System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oExplorer); 
      System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSelection); 
      System.Runtime.InteropServices.Marshal.FinalReleaseComObject(olNS); 

      var olProcess = Process.GetProcessesByName("OUTLOOK").FirstOrDefault(); 

      olApp = null; 
      olNS = null; 

      if (KillOlProcess && olProcess != null) 
      { 
       olProcess.Kill(); 
      } 

      return result; 
     } 

private void RetrieveOutlookProcessHandle(bool forceNewApp) 
     { 
      // Check whether there is an Outlook process running. 
      if (Process.GetProcessesByName("OUTLOOK").Count() > 0) 
      { 
       // If so, use the GetActiveObject method to obtain the process and cast it to an Application object. 
       olApp = Marshal.GetActiveObject("Outlook.Application") as Microsoft.Office.Interop.Outlook.Application; 
       KillOlProcess = false; 
      } 
      else if (!forceNewApp) 
      { 
       // If not, create a new instance of Outlook and log on to the default profile. 
       olApp = new Microsoft.Office.Interop.Outlook.Application(); 
       KillOlProcess = true; 
      } 
      else 
       throw new InvalidOperationException("Outlook must be running or invalid state"); 

      olNS = olApp.GetNamespace("MAPI"); 
     } 

回答

1

這聽起來很像這個問題:

Outlook中,自定義任務窗格和拖放問題:C#,VB.NET http://www.add-in-express.com/creating-addins-blog/2012/03/26/outlook-task-pane-drag-drop/

既然你」不要做自定義拖放,我相信罪魁禍首可能是對MailItem對象的未發佈引用。我會重構遠離foreach並使用一個計數,因爲在迭代集合時,foreach調用在Outlook中是壞消息。

但最重要的是:在完成每個項目後調用ReleaseComObject。

+0

foreach是一個非常好的想法,我的朋友,同時oSelection變量應該是動態的,並通過它作爲集合進行訪問。此外,我正在做自定義拖放。然而,我在WPF中並沒有使用winforms,而是發現了一個更快的解決方案...每次拖動時釋放com對象會在沒有自定義droptargets的情況下離開或放下。因爲MS中的人可能在dragover事件中獲得了IDataObject參考。非常感謝您指點我正確的方向! –

+0

@Vidas你介意在這裏發佈你的解決方案嗎? – Sara