How to add an event handler for reading or opening any mail in Outlook? VSTO

0

The idea of my plugin is that when I click (read) or double click (open) on any email in my Outlook explorer inbox, a windows form is displayed. I understand that I must put the event handler in the ThisAddIn_Startup method to make it work while Outlook is open. I have tried the following:

Outlook.MailItem mailItem = new Outlook.MailItem();
mailItem.Open += new Microsoft.Office.Interop.Outlook.ItemEvents_10_OpenEventHandler(ClickSobreCorreo);
mailItem.Read += new Microsoft.Office.Interop.Outlook.ItemEvents_10_ReadEventHandler(ClickSobreCorreo);
    
Outlook.AppointmentItem Cita = new Outlook.AppointmentItem();
Cita.Open += new Microsoft.Office.Interop.Outlook.ItemEvents_10_OpenEventHandler(ClickSobreCorreo);
Cita.Read += new Microsoft.Office.Interop.Outlook.ItemEvents_10_ReadEventHandler(ClickSobreCorreo);
    
Outlook.MeetingItem Reunion = new Outlook.MeetingItem();
Reunion.Open += new Microsoft.Office.Interop.Outlook.ItemEvents_10_OpenEventHandler(ClickSobreCorreo);
Reunion.Read += new Microsoft.Office.Interop.Outlook.ItemEvents_10_ReadEventHandler(ClickSobreCorreo);

But I get an error:

System.Runtime.InteropServices.COMException (0x80040154): Class not registered (Exception from HRESULT: 0x80040154

Then I tried this that I found on the web but only a random mail works (it is not even the first mail) and the read event only executes once and no more.

    Outlook.MailItem mailItem;

    private void ThisApplication_Startup (object sender, EventArgs e) {
        Outlook.NameSpace ns = this.Session;
        Outlook.MAPIFolder inbox =
            ns.GetDefaultFolder (
                Outlook.OlDefaultFolders.olFolderInbox);

        foreach (object o in inbox.Items) {
            mailItem = o as Outlook.MailItem;
            if (mailItem != null) {
                break;
            }
        }

        if (mailItem == null) {
            MessageBox.Show ("Couldn't find a mail item to connect to.");
        } else {
            MessageBox.Show (String.Format (
                    "Connected to the mail item with subject {0}.",
                    mailItem.Subject);

                mailItem.Read += new Outlook.ItemEvents_10_ReadEventHandler (
                    MailItem_Read);

                mailItem.Open += new Outlook.ItemEvents_10_OpenEventHandler (
                    MailItem_Open);

                mailItem.Write += new Outlook.ItemEvents_10_WriteEventHandler (
                    MailItem_Write);

                ((Outlook.ItemEvents_10_Event) mailItem).Close += new Outlook.ItemEvents_10_CloseEventHandler (
                    MailItem_Close);
            }
        }
    }

    void MailItem_Read() {
        MessageBox.Show("Read");
    }

    void MailItem_Open(ref bool cancel) {
        MessageBox.Show("Open");
    }

    void MailItem_Write(ref bool cancel) {
        MessageBox.Show("Write");
    }

    void MailItem_Close(ref bool cancel) {
        MessageBox.Show("Close");
    }

What should I do? Do I have to go through all the emails and assign the event handler to them? If so, how would you do with the incoming emails, should I add an event handler for the incoming emails and in the method add the event handler to open and read the email?

c#
outlook
vsto
outlook-addin

1 Answer

0

Do not use "new" with Outlook.MailItem - that object is not creatable, Outlook.Application is, but you get an instance of that object (the trusted version) from Outlook anyway.

What I suspect you need to to track the Exploer.SelectionChange event (Explorer can be received from Applica5tion.ActiveExplorer and Application.Explorers.NewExplorer) and set up event handlers on the selected items (Explorer.Selection).

Make sure to keep the objects raising the events (Explorer and Explorers) referenced so they are not garbage collected.


User contributions licensed under CC BY-SA 3.0