How to create a simple office VSTO add-in :A step by step guide

In this short guide I will demonstrate how to create a simply outlook-plugin (VSTO  add-in), consisting of a button that can be clicked in the Ribbon-bar and that will result in some custom action (in this case saving all attachments to your computer).

The reason I wrote this guide is because the standard documentation didn’t really go all-the-way and/or went too deep too fast while creating a plugin I needed (a “Send All Attachments to Calibre” add-in, more info here).

Hence this epic guide.


Let’s go after the fold!

Creating a project (in VS 2015)

Choose an “Outlook 2013 and 2016 VSTO Add-in” project , which can be found under Templates-> Visual C# -> Office/Sharepoint(*shudder*) -> Office Add-ins

If you can’t find the project template, make sure to customize your VS installation by running the setup again.

Statup code…we don’t need that

The boilerplate code that is now shown in the .cs file can be ignored. The startup-method can be used if you need certain stuff to happen every time your plugin loads. Just remember that this usually happens when outlook starts, so make sure you don’t do too much heavy lifting here.

Add a custom ribbon

In this plugin we want our own shiny ribbon and button in outlook. Rightclick your project and choose “Add new Item…”. You can create a Ribbon using XML, or go for the lazy, yet perfectly acceptable way using the Designer. Guess what we choose?! Correct, let’s choose “Ribbon (Visual Designer)”. For now, Ribbon1 is a perfect name for this Ribbon.

Visual Designer: helping students learn to code since 1999.

All the code and design stuff will happen in this newly created file.

RibbonType…Say what?!

Depending on where and when you want your ribbon to show up in Outlook, you might need to change the RibbonType of this new class. DON’t FORGET THIS (I did and had to search far and wide for my just wouldn’t show up).

Select your Ribbon by clicking in the designer on the title of the Ribbon, here “Ribbon1”. In your properties window, you should now see all the properties of your ribbon, including RibbonType. As you can see, there’s a lot of places and moments you might want to show your Ribbon to the user.

Choose wisely, or you might never see your ribbon again!

Some interesting RibbonTypes include:

  • Microsoft.Outlook.Explorer: show ribbon on the main window
  • Microsoft.Outlook.Mail.Compose: show ribbon when composing a new email
  • Microsoft.Outlook.Mail.Read: shown only when opening a mail in a new window (double-clicking mail in explorer view)

Let’s go for Mail.Read.

Add a button

Again in the designer, open your Toolbox. All the usable elements can be found in the “Office Ribbon Controls”. Drag a button to the groupbox (and feel free to change the name of the group and tab. Remember: experimenting is key!)

What would our life be without some buttons to test new code?!

Test what we got!

Ok, let’s see what we got. Make sure to close any running Outlook instances and click the Start+Debug button (F5 for you keyboard-junkies).

Hey, where’s my new Ribbon?! 

Remember that we changed the type to Mail.Read. So, go to your inbox (or any other folder with emails) and double-click on of those spam-mails.

There it is!

Yup. There it is.

For reasons unknown to me, if you happen to have other custom tabs, your new button/groupbox might be added to a previously added tab.

It’s not here? Let’s try and fix that.

If you don’t see the ribbon, first make sure you set the RibbonType to the correct type.

Also, right-click your Ribbon and choose “Customize ribbon…” and make sure you can find “Click me” in the “All tasks” lists.

Sorry for the dutch UI.

What also might happen from time to time is that Outlook has disabled your plugin because it crashed previously. If you start coding , you might from time to time create code that creates unhandled exceptions, if that happens, outlook will block the plugin. Make sure to click the Yellow Ribbon on top of Outlook that asks if you want to (re-)enable the blocked plugin!

Write some code: Let’s save the attachment with an Inspector

Ok, time for some code. Close outlook and come back to Visual Studio.

Double-click the button in the Designer. Aah, good ol’ C# (or VB, if you’re one of those…). Fell free to add something lame as MessageBox.Show(“It works!”); and run your project to see it working. Neat huh. From here on you can basically do anything you can do in .NET (use System.IO, dick around with SQL, harvest passwords, whatever… it’s all yours).

However, if you really want to interact with Outlook, you will have to talk with the Inspector class (in Microsoft.Office.Interop.Outlook) and all the need classes such as MailItem etc.

The following fancy code for example simply checks if the current email has any attachments. If it has, it will save all the attachments to a temp-folder (pro-tip, need a temp-folder, use : System.IO. Path.GetTempPath()). Check it out:

        private void button1_Click(object sender, RibbonControlEventArgs e)
            var m = e.Control.Context as Inspector;
            var mailitem = m.CurrentItem as MailItem;
            if (mailitem != null)
                if (mailitem.Attachments.Count > 0)
                    foreach (Attachment item in mailitem.Attachments)
                        item.SaveAsFile(Path.Combine(@"c:\temp\", item.FileName));
                    MessageBox.Show("This email doesn't have any attachments...");

So what happens here should be pretty straight-forward. The button that gets clicked sends the Context (i.e. where it was clicked) along with the event (in e) and we cast that to our beloved Inspector (i.e. the window currently showing the Outlook item). We then pray and hope it’s an email, and so cast it to an MailItem. From there on we have all the information of the current email (Subject, Body, Flags, etc) including the Attachments, if any.

That’s it?

Yup, that’s pretty much it. As you will discover, Outlook (and the other Office programs) are very customizable. Just have a look at all the interfaces in Office.Interop.Outlook (here) and discover how you can customize every nook and cranny. Have fun!

Wait how about other Office programs?

Just for the sake of lazzyness, I gathered some example code how to do similar stuff in PowerPoint (all code here is from fora and not mine!)

Example 1:

Add some text on current slide when clicking your ribbon-button:

            Microsoft.Office.Interop.PowerPoint.Application p = Globals.ThisAddIn.Application;
            var currentslide = p.ActiveWindow.View.Slide;

            Microsoft.Office.Interop.PowerPoint.Shape ppShap = currentslide.Shapes
                .AddLabel(Microsoft.Office.Core.MsoTextOrientation.msoTextOrientationHorizontal, 0, 0, 200, 250);

            ppShap.TextEffect.Text = "ADDED NOW";

Example 2:

Add text to every new slide you add in PowerPoint, including the first one (all the time!):

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
            this.Application.PresentationNewSlide +=
               new PowerPoint.EApplication_PresentationNewSlideEventHandler(

        void Application_PresentationNewSlide(PowerPoint.Slide Sld)
            PowerPoint.Shape textBox = Sld.Shapes.AddTextbox(
                Office.MsoTextOrientation.msoTextOrientationHorizontal, 0, 0, 500, 50);
            textBox.TextFrame.TextRange.InsertAfter("Property of Tim Dams");



About timdams
C#, .NET, Microsoft, security, .... Read more on :

3 Responses to How to create a simple office VSTO add-in :A step by step guide

  1. ida says:

    Thank you for the tutorial. Quite straight forward and gave me the courage to experiment more đŸ™‚

  2. Stephu says:

    Nice article. Was very helpfull for a fast start!
    Do you know if it is possible to use an app.config file to customize for example? I have to change for example the image inside the ribbon button on some clients or change for example some text which will be shown inside a dialog if the use presses the ribbon button.

    • timdams says:

      Hi Stephu,
      Thanks for the comment. I haven’t looked into the app.config part, but I would think this shouldn’t be a problem.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: