Question

I'm trying to get the MAPIOBJECT of the MailItem.AddressEntry using Late Binding with Outlook.

I keep getting "Exception has been thrown by target of invocation" and an inner exception of "Specified Cast is Invalid" and I have no idea why. Nothing has come up on Google searches etc.

Firstly I know that the MAPIOBJECT is deprecated and not visible through intellisense but works.

I can get the object no problems without late binding.

Here is the code:

/// <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);
        }
    }
}
Was it helpful?

Solution

Unless you have to use the MAPI interface as you are, I would strongly recommend using the MAPIEx project in CodeProject.

This made our MAPI integration go very, very smoothly.

And, worst case, the source code could shed light on specific questions, such as this.

OTHER TIPS

Firstly, MAPIOBJECT is not deprecated, just invisible. Secondly, where does your code run? If it is an exe other than outlook.exe (i.e. your code is not in a COM add-in), you must call MAPIInitialize().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top