MAPISendMail doesn't work when Outlook is running

9.2k views Asked by At

I've been using Mapi32 from a Winforms app to send bring up a new mail message with attachments for a while now, and it's worked really well. (Yes, I'm aware that calling into MAPI32 from C# is not supported.)

Within the last few days, it has stopped working when Outlook is running. However, if Outlook is not running, it will work as expected. This happens in both Vista and XP.

Have any SOer's had this problem? How did you resolve it?

Here's the code I've been using:

public class EmailController
{
    [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
    public static extern int MAPISendMail(IntPtr lhSession, IntPtr ulUIParam,
        MapiMessage lpMessage, int flFlags, int ulReserved);
    public const int MAPI_LOGON_UI = 0x00000001;
    private const int MAPI_DIALOG = 0x00000008;

    public static int SendMail(string strAttachmentFileName, string strSubject,string to)
    {

        IntPtr session = new IntPtr(0);
        IntPtr winhandle = new IntPtr(0);

        MapiMessage msg = new MapiMessage();
        msg.subject = strSubject;

        int sizeofMapiDesc = Marshal.SizeOf(typeof(MapiFileDesc));
        IntPtr pMapiDesc = Marshal.AllocHGlobal(sizeofMapiDesc);

        MapiFileDesc fileDesc = new MapiFileDesc();
        fileDesc.position = -1;
        int ptr = (int)pMapiDesc;

        string path = strAttachmentFileName;
        fileDesc.name = Path.GetFileName(path);
        fileDesc.path = path;
        Marshal.StructureToPtr(fileDesc, (IntPtr)ptr, false);

        msg.files = pMapiDesc;
        msg.fileCount = 1;


        List<MapiRecipDesc> recipsList = new List<MapiRecipDesc>();
        MapiRecipDesc recipient = new MapiRecipDesc();

        recipient.recipClass = 1;
        recipient.name = to;
        recipsList.Add(recipient);

        int size = Marshal.SizeOf(typeof(MapiRecipDesc));
        IntPtr intPtr = Marshal.AllocHGlobal(recipsList.Count * size);

        int recipPtr = (int)intPtr;
        foreach (MapiRecipDesc mapiDesc in recipsList)
        {
            Marshal.StructureToPtr(mapiDesc, (IntPtr)recipPtr, false);
            recipPtr += size;
        }

        msg.recips = intPtr;
        msg.recipCount = 1;
        int result = MAPISendMail(session, winhandle, msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);

        return result;
    }
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiMessage
{
    public int reserved;
    public string subject;
    public string noteText;
    public string messageType;
    public string dateReceived;
    public string conversationID;
    public int flags;
    public IntPtr originator;
    public int recipCount;
    public IntPtr recips;
    public int fileCount;
    public IntPtr files;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiFileDesc
{
    public int reserved;
    public int flags;
    public int position;
    public string path;
    public string name;
    public IntPtr type;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
    public int reserved;
    public int recipClass;
    public string name;
    public string address;
    public int eIDSize;
    public IntPtr entryID;
}
3

There are 3 answers

0
Flatliner DOA On

If you're application is running with Elevated Privileges (i.e. as Administrator) and Outlook isn't, the send will fail. You will have to tell the user to close all running instances of Outlook and try again.

0
Jared Harley On

Well, other than the obvious "use supported C# mail-sending methods" comment, I wonder if something happened to the mapi32.dll file - have you tried a "Detect and Repair" in Outlook?

I also read here (http://office.microsoft.com/en-us/outlook/HP011164781033.aspx) that there are some steps you can do (the post and the comments) to get Outlook to repair or replace the dll.

2
André van Schoubroeck On

int result = MAPISendMail(session, winhandle, msg, MAPI_LOGON_UI | MAPI_DIALOG, 0);

   return result;

What does it return?