1

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;
}
Jon Dewees
  • 2,957
  • 6
  • 31
  • 38
  • 1
    Probably integrity level of caller process is different than Outlook's integrity level. Use Process Explorer to find ILs of running processes. – wqw Nov 22 '12 at 12:30
  • may be not related to your problem, but I had `MAPISendMail` hanging with Outlook because the mail addresses had trailing spaces! – Ivan Ferrer Villa Nov 15 '17 at 12:50

3 Answers3

4

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.

Flatliner DOA
  • 6,128
  • 4
  • 30
  • 39
1

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

   return result;

What does it return?

  • I also tested the way to send email. My tests doesn't send email, method MAPISendMail returns 2. – constructor Nov 09 '15 at 09:38
  • It's quite a while ago since I was into MAPI. However, verify you have configured an email client to be used with MAPI, as by default, this value is not set. See https://msdn.microsoft.com/en-us/library/windows/desktop/ee909492%28v=vs.85%29.aspx – André van Schoubroeck Nov 10 '15 at 10:12
0

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.

Jared Harley
  • 8,219
  • 4
  • 39
  • 48