2012-01-10 27 views
1

我試圖使用Outlook的Late Binding來獲取MailItem.AddressEntry的MAPIOBJECT。指定的演員無效從MailItem.AddressEntry使用後期綁定獲取MAPIOBJECT

我不斷收到「異常已被調用目標拋出」和「指定的演員無效」的內部異常,我不知道爲什麼。谷歌搜索等什麼都沒有出現。

首先,我知道MAPIOBJECT已被棄用,並且通過智能感知不可見,但是可行。

沒有遲綁定,我可以得到對象沒有問題。

下面是代碼:

/// <summary> 
/// Gets the MAPI Object from the AddressEntry of the new recipient. 
/// </summary> 
/// <param name="senderName">The name of the sender to add to the recipients.</param> 
/// <param name="outlookApplication">The Outlook Application instance.</param> 
private static object GetMapiObject(string senderName, object outlookApplication) 
{ 
    var mailItem = InvokeMember("CreateItem", outlookApplication, new object[] { 0 }); 
    var recipients = GetProperty("Recipients", mailItem); 
    var recipient = InvokeMember("Add", recipients, new object[] { senderName }); 

    InvokeMember("Resolve", recipient, new object[] {}); 
    var addressEntry = GetProperty("AddressEntry", recipient); 

    var mapiObject = GetProperty("MAPIOBJECT", addressEntry); // Error occurs here. 
    return mapiObject; 
} 

/// <summary> 
/// Gets a property of an instance by its name 
/// </summary> 
/// <param name="propertyName">The property name to get.</param> 
/// <param name="instance">The object to get the property from.</param> 
/// <returns>The resulting object.</returns> 
private static object GetProperty(string propertyName, object instance) 
{ 
    Type type = instance.GetType(); 
    return type.InvokeMember(propertyName, BindingFlags.GetProperty, null, instance, new object[] { }); 
} 

/// <summary> 
/// Invoke an object by its method and type - takes parameters. 
/// </summary> 
/// <param name="method">The method to invoke.</param> 
/// <param name="instance">The object that contains the method to invoke.</param> 
/// <param name="parameters">The parameters to pass to the method.</param> 
/// <returns>The resulting object.</returns> 
private static object InvokeMember(string method, object instance, object[] parameters) 
{ 
    try 
    { 
     Type type = instance.GetType(); 
     return type.InvokeMember(method, BindingFlags.InvokeMethod, null, instance, parameters); 
    } 
    catch (Exception ex) 
    { 
     switch (method) 
     { 
      case "SaveAsFile": 
       throw new System.IO.IOException("Error occurred during \"SaveAsFile\" for attachments. Attachment filename may be too long. ", ex);             

      default: 
       throw new TargetInvocationException("Handled error at Invoke Member. Method Name: " + method, ex); 
     } 
    } 
} 

回答

2

除非你必須像現在一樣使用MAPI接口,否則我會強烈建議在CodeProject中使用MAPIEx項目。

這使得我們的MAPI集成非常順利。

而且,最糟糕的情況是,源代碼可以闡明具體問題,比如這個。

+0

謝謝,我結束了使用!這非常有幫助,並允許我做我以後的事情。 – doiley 2012-01-11 03:55:33

+3

有一項關於託管MAPI的全新高質量**文章(http://www.codeproject.com/Articles/455823/Managed-MAPI-Part-1-Logon-MAPI-Session-and -Retriev)在Code Project上。 – 2012-09-20 03:51:38

1

首先,MAPIOBJECT不會被棄用,只是不可見。其次,你的代碼在哪裏運行?如果它是除outlook.exe以外的其他exe(即,您的代碼不在COM加載項中),則必須調用MAPIInitialize()。

+0

MSDN說這是貶值。我的代碼在Outlook外運行。我試着在這行之前添加:var mapiObject = GetProperty(「MAPIOBJECT」,addressEntry);但無濟於事。這是正確的調用:MAPIInitialize(IntPtr.Zero); – doiley 2012-01-11 00:16:54

+0

是的,這應該工作。怎麼了?爲什麼你需要IMailUser MAPI對象? – 2012-01-17 14:24:40

+0

阿洛斯,你確定你打電話MAPIInitialize出口從正確的DLL? – 2012-01-18 16:37:45