mmlschadegg
mmlschadegg

Reputation: 23

Outlook interop sent mail event not triggered in WPF but works in Console Application

In my C# WPF application I am sending mail using Outlook Interop. After the mail is sent, I want to retrieve it from the Sent folder for some postprocessing.

I've created the following class to encapsulate the Outlook interaction:

public class OutlookManager {
    public MAPIFolder SentMailFolder { get; set; }

    public Application MailApplication { get; set; }

    public OutlookManager() {
      MailApplication = new Application();
      SentMailFolder = MailApplication.Session.GetDefaultFolder(OlDefaultFolders.olFolderSentMail);
    }
}

If I use this class in a Console Application project, it works fine. The method SentMailHandler is run when Outlook sends the email, and the subject is written in the terminal window:

private static void SentMailHandler(object item) {
  var mail = (MailItem)item;
  Console.WriteLine(mail.Subject);
}

private static void Main() {
  OutlookManager Outlook = new OutlookManager();
  Outlook.SentMailFolder.Items.ItemAdd += SentMailHandler;
  MailItem mail = Outlook.MailApplication.CreateItem(OlItemType.olMailItem);
  mail.To = "my-address";
  mail.Subject = "Testing";
  mail.Body = "This is a test";
  mail.Send();

  Console.Read();
}

However, when I try to incorporate the same code in my WPF application, nothing happens when the mail is sent, i.e. the SentMailHandler method is never run, and nothing is printed in the Debug window. I have a context class MassMailContext. An instance of this class is created and set as the DataContext of a UI element (I am certain the constructor code is run):

internal class MassMailContext : Context {
   public OutlookManager Outlook { get; set; }

   public MassMailContext(MainWindow view) : base(view) {
      Outlook = new OutlookManager();
      Outlook.SentMailFolder.Items.ItemAdd += SentMailHandler;
      MailItem mail = Outlook.MailApplication.CreateItem(OlItemType.olMailItem);
      mail.To = "my-address";
      mail.Subject = "Testing";
      mail.Body = "This is a test";
      mail.Send();
   }

   private void SentMailHandler(object item) {
      var mail = (MailItem)item;
      Console.WriteLine($"{mail.Subject}");
   }
}

Note that the mail is not intended to be sent from the constructor, but is only done her for debugging purposes.

Why does it work in a Console Application project, but not in a WPF application project? The only difference I can see is, that the Main() method of the Console Application project is still in scope when the email is sent, while this is not true for the MassMailContext constructor.

Upvotes: 0

Views: 123

Answers (1)

Dmitry Streblechenko
Dmitry Streblechenko

Reputation: 66255

The object raising the events (Items) must be alive to raise the events. You are setting your event handler on a temporary variable created by the compiler. As soon as it goes out of scope, it will be subject to the garbage collection.

Introduce a class member that holds the Items object and set the event handler on that variable.

Upvotes: 1

Related Questions