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?
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.