GetItemFromID()上的Outlook加载项ComException

时间:2015-01-12 19:36:20

标签: c# com outlook vsto outlook-addin

我有一个 Outlook 2013加载项,我在其中处理传入的电子邮件:

void ThisAddIn_Startup(object sender, EventArgs e)
{
   ... other code ...
   Application.NewMailEx += GetEmail;
   ...
}

void GetEmail(string ID)
{
   try
   {
      var email = Application.Session.GetItemFromID(ID) as Outlook.MailItem; // COMExeption
      var email = Application.Session.GetItemFromID(ID);  // No casting - COMException 
   }
   ...
}

当新的电子邮件来自外部(SMTP)电子邮件地址时,电子邮件处理得很好。在测试时,当我发送日历会议请求时,当该邮件到达时,我得到以下异常:

[Exception Type]: 
 System.Runtime.InteropServices.COMException 
 [Aggregate Exception]: 
 The message you specified cannot be found. 
 [Stack Trace]: 
    at Microsoft.Office.Interop.Outlook.NameSpaceClass.GetItemFromID(String EntryIDItem, Object EntryIDStore)
   at EmailHelper.ThisAddIn.GetEmail(String entryId) in c:\EmailHelper\ThisAddIn.cs:line 44 

我尝试了几种不同的解决方法,但没有运气,总会抛出异常,例如。

  1. 致电GetItemFromID(ID, IDStore);
  2. 致电GetItemFromID(ID, Type.Missing);
  3. 我可能会遗失什么?

2 个答案:

答案 0 :(得分:-1)

会议请求不是消息,但您的代码假定它是MailItem对象。会议请求由MeetingItem对象表示。

使用"是"或" as"运算符或使用反射检索Class属性以确定它是什么类型的对象。

答案 1 :(得分:-1)

与emily_bma相同。而EmailItem或其他与COMException所提出的任何内容无关,这似乎是随机出现的。有时您会收到此错误,有时则不会。就好像通知在消息注册之前到来。当然,我的Outlook中严格没有规则,这只是一个仅用于开发和测试目的的新实例。

因此,经过几次尝试和阅读后,我发现使用以下代码而不是Application.Session.GetItemFromID实际上提供了更好的结果:

Outlook.NameSpace nameSpace = Application.GetNamespace("MAPI");
var item = nameSpace.GetItemFromID(entry.Trim(), Type.Missing);

至于完整的源代码:

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    Application.ItemSend += Application_ItemSend;
    Application.NewMailEx += Application_NewMailEx;
}

void Application_NewMailEx(string EntryIDCollection)
{
#if !OLD_METHOD
    Outlook.NameSpace nameSpace = Application.GetNamespace("MAPI");
#endif
    string[] arr = EntryIDCollection.Split(',');
    foreach(string entry in arr)
    {
#if OLD_METHOD
        var item = Application.Session.GetItemFromID(entry.Trim(), Type.Missing);
#else
        var item = nameSpace.GetItemFromID(entry.Trim(), Type.Missing);
#endif
        // COMException is thrown there quite often when entry is a meeting.

        if (item is Outlook.MailItem)
        {
            // ... Do something with the email
        }
        else if (item is Outlook.AppointmentItem)
        {
            // ... Do something with the appointment
        }
        else if (item is Outlook.MeetingItem)
        {
            // ... Do something with the meeting
        }
    }
}