0
votes

I'm trying to send emails from a .NET application using Outlook Object Model.

My application displays the Outlook message window so the user can see what we're sending and edit it first. When the user hits the Send button, the Outlook window closes, and the message gets sent. This works perfectly as long as the Outlook application is already running.

If the Outlook application isn't already running, the message gets stuck in the Outbox, and will not send until I start Outlook. When I start Outlook, I can see the message sitting in the Outbox folder for a few seconds, then it gets sent.

Here is a simplified version of the code I'm using to send the email:

Outlook.Application app = new Outlook.Application();
var ns = app.GetNamespace("MAPI");

// (ref: https://msdn.microsoft.com/en-us/library/office/ff861594.aspx)
// If outlook is already running, this does nothing.  If it isn't, this has the 
// side-effect of initializing MAPI to use the default profile and make the object 
// model fully functional
var mailFolder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);

var mailItem = (Outlook.MailItem)ns.Application.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.To = "[email protected]";
mailItem.Subject = "This is a test";
mailItem.HTMLBody = "<html>A bunch of HTML</html>";

mailItem.Display(true);

NOTE: If I replace the call to mailItem.Display() with mailItem.Send(), it works whether Outlook is running or not. Unfortunately that's not an option, because I need the user to be able to edit the message before sending it.

I'm thinking I need a way to detect when the message has finished sending, and keep the Outlook.Application object alive until then...but I'm not sure how to do that. My app is a console application that needs to exit after sending the email. Putting the thread to sleep for awhile doesn't do it (probably because whatever I'm waiting for is happening on that same thread).

1

1 Answers

1
votes

Outlook will exit if no more windows (explorers or inspectors) are open or referenced.

Reference an inspector object, retrieve the first SyncObject object from Namespace.SyncObjects and wait for the SyncObject.SyncEnd event to fire.

insp = mailItem.GetInspector;
insp.Display(true);
//keep insp referenced