(Print this page)

Creating an Add-In for Outlook in .Net
Published date: Thursday, December 21, 2017
On: Moer and Éric Moreau's web site

Outlook is a great tool, I love it. My life is in there! But there is one feature that used to be provided 10 years ago which is not available anymore. That feature is a possibility of showing appointments from multiple calendars into the Calendar pane. I have, surely like most of you, many email addresses provided by my clients, each mailbox having a distinct calendar. I know you can get a combined view in the calendar view but not in the Calendar pane which is sitting right next to your list of emails, always visible. I missed that feature a lot until I found some code (developed for an older version of Visual Studio and Outlook) which was not working so great for my needs.

Figure 1: Toggling on/off the main Calendar pane

This article will show you how to create your own add-on to display your appointments from multiple calendars into a pane of Outlook 2017.

The downloadable code

This solution contains only a C# project (sorry VB but no time to convert the code this month!). The solution has been created using Visual Studio 2017 and tested against Outlook 2016.

Code is made available in the downloadable solution that won’t be pasted in this article. There would just be too much to show. So you better download this solution and copy and paste classes when required.

You will need VSTO in order to create (or compile) a solution like this one. From what I have read and understood, VSTO is not available in the free versions (like the Community edition). If you have the proper edition of Visual Studio and still cannot find the project type, visit Configuring a Computer to Develop Office Solutions for additional details.

Creating the Project

To create the add-in project, select “Outlook 2013 and 2016 VSTO Add-in” from the New Project dialog as show in Figure 2. This will create a project specific to Office add-ins with a few methods already hooked up for Office. A few references will also be added to your project.

Figure 2: Creating the new Add-in project

A first test

Before writing a lot of code, you might want to check if your setup is compatible.

In your project, find the class that was generated for you named ThisAddIn.cs, add the following member at the top of your class:

Microsoft.Office.Interop.Outlook.Inspectors inspectors;

Find the Startup method and add these 2 lines of code to it:

inspectors = this.Application.Inspectors;
inspectors.NewInspector += Inspectors_NewInspector;

Finally, you need to create NewInspector event handler with this code:

private void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
    Microsoft.Office.Interop.Outlook.MailItem mailItem = Inspector.CurrentItem as Microsoft.Office.Interop.Outlook.MailItem;
    if (mailItem != null)
    {
        if (mailItem.EntryID == null)
        {
            mailItem.Subject = "custom subject created by the add-in";
            mailItem.Body = "This body was created by your add-in. Isn't it wonderful?";
        }
    }
}

This is all you need for your first test! Go ahead and hit F5 to run your project. Chances are that you will hit your very first error if like me, your Outlook application is always opened.

Figure 3: Outlook needs to be closed before testing the add-in

The reason is that in order to attach your add-in from Visual Studio to Outlook, some registry entries needs to be created to enable Outlook to discover the add-in and security settings need to be set on the development computer. To resume your test, click the OK button on the error, close Outlook and return to Visual Studio to hit F5. Now your Outlook application will be launched by Visual Studio and your add-in will be attached to Outlook. To prove it, create a new email and you should see the new email dialog popping out with the subject and the body already filled as shown in figure 4.

Figure 4: Your first add-in in action

Before stopping this test, I’ll show you a great feature, the main reason why we run the add-in directly from Visual Studio. Go back to Visual Studio (without closing Outlook or stopping your add-in), place a break point in the Inspectors_NewInspector event handler and, from Outlook, create a new email again. Visual Studio should stop the execution and let you debug your add-in just like you are used to.

Now close Outlook or stop debugging from Visual Studio. Whichever action you do, will also stop the other one because they go hand-in-hand.

When cleaning is required

Sometimes during the development of an add-in, you might find that your add-in is not behaving the way you are expecting, and that your debugging session is not in line with your code.

To try to clean up the mess, you should use “Clean Solution” from the Build menu in Visual Studio.

This clean-up should also be done when you are finished developing your add-in project.

Back to square one

Remember, my dream is not to have text added automatically to new emails, it is to see the appointments of selected email accounts all in one pane.

You can either create a new Visual Studio project of just delete the few lines created in the previous step.

As said earlier, there would be way too much code to show here if everything would be shown here.

Files you need to copy

Here are some files used by the add-in that will not show full code here:

  • CustomCalendar.cs: This file is in charge of displaying a calendar control at the top of the pane. Dates with appointments will be bolded.
  • FormConfiguration.cs: This file is a small dialog to let the user configure the add-in.
  • FormRecurringOpen.cs: This file asks a question about recurring appointments.
  • AppointmentRibbonAddIn.cs: A custom ribbon to show in Outlook.

You will also need to create some entries into Settings.Settings as shown in figure 5.

Figure 5: Settings needed

One image is also needed in the resources of the project to show on the ribbon of Outlook.

Figure 6: Resources needed

Finally, ready to write some code

With the previous files in place, you can return to the ThisAddin class and add the following code:

public AppointmentsControl AppControl { get; set; }
public Microsoft.Office.Tools.CustomTaskPane AppointmentTaskPane { get; set; }

private void ThisAddIn_Startup(object sender, EventArgs e)
{
    try
    {
        AddRegistryNotification();

        AppControl = new AppointmentsControl
        {
            ShowPastAppointments = Properties.Settings.Default.ShowPastAppointments,
            Accounts = Properties.Settings.Default.Accounts,
            NumDays = Properties.Settings.Default.NumDays
        };

        AppointmentTaskPane = CustomTaskPanes.Add(AppControl, "Appointments");
        AppointmentTaskPane.Visible = Properties.Settings.Default.Visible;
        AppointmentTaskPane.Width = Properties.Settings.Default.Width;
        AppointmentTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
        AppointmentTaskPane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoHorizontal;
        AppointmentTaskPane.VisibleChanged += AppointmentTaskPane_VisibleChanged;

        AppControl.SizeChanged += appControl_SizeChanged;
        AppControl.SelectedDate = DateTime.Today;

        Globals.ThisAddIn.Application.ActiveExplorer().Deactivate += ThisAddIn_Deactivate;
    }
    catch (Exception exc)
    {
        MessageBox.Show($"Error starting Calendar AddIn: {exc}");
        throw;
    }
}

private void appControl_SizeChanged(object sender, EventArgs e)
{
    Properties.Settings.Default.Width = AppointmentTaskPane.Width;
}

private void AppointmentTaskPane_VisibleChanged(object sender, EventArgs e)
{
    AppointmentRibbonAddIn rbn = Globals.Ribbons.FirstOrDefault(r => r is AppointmentRibbonAddIn) as AppointmentRibbonAddIn;
    if (rbn != null)
        rbn.toggleButton1.Checked = AppointmentTaskPane.Visible;
}

private void ThisAddIn_Deactivate()
{
    Properties.Settings.Default.Visible = AppointmentTaskPane.Visible;
}

private void ThisAddIn_Shutdown(object sender, EventArgs e)
{
    // Note: Outlook no longer raises this event. If you have code that 
    //    must run when Outlook shuts down, see https://go.microsoft.com/fwlink/?LinkId=506785
    Properties.Settings.Default.Save();
}

/// Implement shutdown notification for this particular add-in
/// http://msdn.microsoft.com/en-us/library/office/ee720183.aspx#OL2010AdditionalShutdownChanges_AddinShutdownChangesinOL2010Beta
/// HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\Addins\ProgID\[RequireShutdownNotification]=dword:0x1
private void AddRegistryNotification()
{
    // If the entry is not there when Outlook loads, it will NOT notify the add-in, so the first time won't save the results
    string subKey = @"Software\Microsoft\Office\Outlook\Addins\EMoreauDemoOutlookAddinCS";
    RegistryKey rk = Registry.CurrentUser.OpenSubKey(subKey, true);
    if (rk == null)
    {
        rk = Registry.CurrentUser.CreateSubKey(subKey);
    }
    if (rk != null && (int)rk.GetValue("RequireShutdownNotification", 0) == 0)
    {
        rk.SetValue("RequireShutdownNotification", 1, RegistryValueKind.DWord); 
    }
}

The Startup event is initializing the various controls using the persisted settings (see note from the “One strange bug” section). There is some code in there to show/hide the add-in based on the toggle from the ribbon.

If you now hit F5, you should be able to see your new add-in loaded in Outlook. Clicking on the blue button below the calendar (labelled C), you will see a configuration dialog showing and letting you pick the calendars you want to display.

Figure 7: Your new add-in in action

One strange bug

One really strange bug that is left that I can’t figure out what’s happening is that the first time the add-in is loaded, it won’t persist your settings.

I suggest that you launch the Outlook with the add-in once, close it and then restart it before changing any settings.

Deployment

Now that you have your add-in, you will surely want to deploy it to some users/friends. That is explained in Deploying an Office Solution.

Conclusion

Thanks to the way Office was built, it is possible for you to extend some features of that tool. It takes quite some code but in the end, it is really worth it!

If you have ideas in developing more tools for Office, you should really visit “Create VSTO Add-ins for Office by using Visual Studio” (https://msdn.microsoft.com/en-us/library/jj620922.aspx).

You may also find some interesting notes in How to Create an Add-in for Microsoft Outlook.

I hope you will enjoy your new add-in.

And if you ever find a commercial add-in that does something like this, let me know!


(Print this page)