I have a 32-bit Windows Forms application that uses PInvoke to call the MAPI methods to generate emails with attachments. Its been working for years without issue.
I then got the request to support the 64-bit version of Outlook. As a 32-bit application can't use MAPI for a 64-bit mail client I ended up creating a simple 64-bit executable that is launched from the 32-bit application.
All was well, or so I thought, as my application could now send emails using both the 32-bit and 64-bit versions of Outlook Office 365. As the months went on we started to get complaints from customers that the email feature was broken with Outlook 2013. Groan!
Behavior
When attempting to call MAPI with Outlook 2013 as the default mail client, the MAPILogon method would fail with return code 3 (MAPI_E_LOGON_FAILURE/MAPI_E_LOGIN_FAILURE). No logs or explanations that I could find. After a lot of research and testing I finally found the root cause.
Calling MAPI on a background worker thread
When supporting the 64-bit Outlook, I decided to task off the operation because I'm impatient.
Task.Run(() =>
{
if (!SendMail32(recipient, subject, body, attachments))
{
SendMail64(recipient, subject, body, attachments);
}
});
The in process method, SendMail32, calls the MAPI methods directly and failed when Outlook 2013 was the default mail provider. Removing the Task.Run resolved the issue for the 32-bit version of Outlook. My theory is that the MAPI calls have to be made on the main UI thread so that the default mail profile can be found/used. I don't know why this isn't an issue with Office 365.
Single threaded apartment model
{
[STAThread]
static int Main(string[] args)