1

As the title suggests, I have a Winform written in C# .Net Framework 4.8; it calls the MAPISendMail external function from the mapi32.dll to open up a new message window in Outlook for the user, initially populated with a to address and message (and sometimes an attachment):

[DllImport("MAPI32.DLL")]
public static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flg, int rsv);

NOTE: If there is anything that you know that could replace MAPI for the usage described, that would be phenomenal.

For whatever reason, every now and again this will end up causing the whole winform to hang for a bit, then close. There is no indication that this is going to happen aside from the aforementioned hanging, and no pattern as far as I can tell; I can go hours without ever encountering it.

Additionally, NO try/catch blocks will be caught when this happens. I have tried catching the standard Exception of course, but also RuntimeWrappedException and that doesn't get triggered either:

try
{
    error = MAPIHelperInterop.MAPISendMail(IntPtr.Zero, IntPtr.Zero, message, MAPI_DIALOG, 0);
}
catch (RuntimeWrappedException rwe)
{
    throw rwe.InnerException;
}
catch (Exception e)
{
    throw e;
}

The only indication that something is wrong is the final line in the Debug output, stating "The program 'PROGRAMNAME' has exited with code 40445582 (0x269268e)". I have googled my hands off trying to find a meaning to this code and have found nothing. Does anyone have any insight on what could be going on here, maybe even a way I can catch this error to prevent the form from closing?

C Howell
  • 51
  • 6
  • Read following page : http://www.pinvoke.net/default.aspx/mapi32.MAPISendMail – jdweng Sep 15 '20 at 21:20
  • 4
    [Don't do it](https://learn.microsoft.com/en-us/archive/blogs/mstehle/fyi-why-are-mapi-and-cdo-1-21-not-supported-in-managed-net-code). – Hans Passant Sep 15 '20 at 21:37
  • @HansPassant Yeah I had a feeling there was something funky going on with MAPI itself. Are you aware of a good replacement to open up a new email your default email program w/ a subject, to, and attachment? – C Howell Sep 16 '20 at 12:39
  • 1
    @CHowell Unfortunately there seemingly isn't any way to do it with attachments as it's considered a security risk. MAPI is a deprecated API, you should avoid using it if at all possible as it's likely to disappear entirely at some point in the future. I appreciate this is unlikely to be problematic for your users if they are used to this functionality, but letting them know you're removing the feature, and then removing it, is a far better solution than waiting for Microsoft to remove it, and then panicking. – Ian Kemp Sep 16 '20 at 14:16
  • @IanKemp yeah from all I've seen, MAPI should be excised. I DID find this [other SO question](https://stackoverflow.com/questions/6148639/how-to-open-outlook-new-mail-window-c-sharp) from 2011 where they got it to work w/ microsoft.office.interop.outlook! I tested it out and it seems to work fine, but it hasn't been updated since 2016. I can't find anything indicating that it has any vulnerabilities, but would you suggest not using it anyway due to how long it's been since it was updated? – C Howell Sep 16 '20 at 14:56
  • 1
    The big problem of using the Outlook interop is that it presumably won't work with any email client besides Outlook, whereas MAPI will work (as well as MAPI works) with whatever the system default email client is. If you only care about Outlook, then interop is definitely the way to go - just make sure you use the official NuGet package (https://www.nuget.org/packages/Microsoft.Office.Interop.Outlook/) instead of trying to hard-link your application to the interop DLLs. The API definitely hasn't changed much so the answer you found should still be good. – Ian Kemp Sep 16 '20 at 15:08
  • 1
    In that case, I'm lucky that I KNOW all of my users are using Outlook! Thank you for your help. I would upvote both you AND @HansPassant if I had +15 reputation. – C Howell Sep 16 '20 at 15:38

1 Answers1

3

I was essentially asking the wrong question. Thanks to Hans Passant and Ian Kemp for pointing out MAPI is long deprecated and should be avoided.

In its place, I used Microsoft.Office.Interop.Outlook thanks to this SO question and made a very simple wrapper class:

    public class OutlookEmail
    {
        public OutlookEmail() { }
        public OutlookEmail(params string[] toAddrs)
        {
            To.AddRange(toAddrs);
        }
        private Application OApp = new Application();
        public List<string> To { get; set; } = new List<string>();
        public string Subject { get; set; }
        public string Body { get; set; }
        public List<string> Attachments { get; set; } = new List<string>();
        public void ShowDialog()
        {
            _MailItem oMailItem = (_MailItem)OApp.CreateItem(OlItemType.olMailItem);
            oMailItem.To = string.Join("; ", To);
            // body, bcc etc...
            oMailItem.Subject = Subject;
            oMailItem.Body = Body;
            if(Attachments != null)
            {
                foreach (string path in Attachments)
                {
                    oMailItem.Attachments.Add(path);
                }
            }

            oMailItem.Display(true);
        }
    }

NOTE: this will ONLY work for Outlook; luckily for me, ALL of my users definitely use Outlook.

C Howell
  • 51
  • 6