Writing a context menu outlook addin

There is a sizable amount of documentation around about writing outlook addins, but few complete samples that cover the basics, and only the basic. Documentation snippets are great to get started, full blown applications are good if you dig around in addins daily.

This snippet covers the middle ground: It is (the) complete framework you need to add an item to the context menu in outlook and start a processing action on it after perfoming the minimal validation like a check to see if you didnt select multiple items, and a check to see if the selected item actualy is a mail item. Finaly, the selected item is retrieved when the menu item is clicked at which point it is ready for further processing.

From this point, you can pick up further processing of the item either in the AddIn, or in a seperate application. With a little digging around in the documentation and what the internet has to offer i came up with the following fully functional example for Outlook 2007 and later.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Outlook;
using stdole;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using System.Drawing;
using System.Windows.Forms;
namespace Kakofonix
    public partial class ThisAddIn
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
            Application.ItemContextMenuDisplay += ApplicationItemContextMenuDisplay;
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        #region VSTO generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        // Outlook menu item
        // This triggers whenever a mailitem is rightclicked, and gets a "selection" object passed which contains all selected items
        void ApplicationItemContextMenuDisplay(CommandBar commandBar, Selection selection)
            var cb = commandBar.Controls.Add(Office.MsoControlType.msoControlButton, missing, missing, missing, true) as Office.CommandBarButton;
            if (cb == null) return;
            cb.Visible = true;
            cb.Picture = ImageConverter.ImageToPictureDisp(Properties.Resources.Desktop.ToBitmap());    // some icon stored in the resources file
            cb.Style = MsoButtonStyle.msoButtonIconAndCaption;                                          // set style to text AND icon
            cb.Click += new _CommandBarButtonEvents_ClickEventHandler(AsterixHook);                     // link click event
            // single MailItem item selection only, NOT 0 based
            if (selection.Count == 1 && selection[1] is Outlook.MailItem)
                var item = (MailItem)selection[1];                          // retrieve the selected item
                string subject = item.Subject;
                if (subject.Length > 25) subject = subject.Substring(0, 25);// limit max length of the caption
                cb.Caption = "Kakofonix => " + subject;                     // set caption
                cb.Enabled = true;                                          // user selected a single mail item, enable the menu
                cb.Parameter = item.EntryID;                                // this will pass the selected item's identification down when clicked
                cb.Caption = "Kakofonix: Invalid selection";
                cb.Enabled = false;
        // Runs when the actual context menu item is clicked
        private void AsterixHook(CommandBarButton control, ref bool canceldefault)
            string entryid = control.Parameter;                                     // the outlook entry id clicked by the user
            var item = (MailItem)this.Application.Session.GetItemFromID(entryid);   // the actual item
            MessageBox.Show(item.SenderEmailAddress + " " + item.Subject);          // display sender email & subject line
            // further processing