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

In this short guide, I will show 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 that 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.

Startup 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. Right-click 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…). Feel 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:

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

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 a 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 laziness, I gathered some example code on how to do similar stuff in PowerPoint (all code here is from fora and not mine!)

Example 1:

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

<p>            Microsoft.Office.Interop.PowerPoint.Application p = Globals.ThisAddIn.Application;<br>
            var currentslide = p.ActiveWindow.View.Slide;</p>
<p>            Microsoft.Office.Interop.PowerPoint.Shape ppShap = currentslide.Shapes<br>
                .AddLabel(Microsoft.Office.Core.MsoTextOrientation.msoTextOrientationHorizontal, 0, 0, 200, 250);</p>
<p>            ppShap.TextEffect.Text = "ADDED NOW";</p>

Example 2:

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

<p>        private void ThisAddIn_Startup(object sender, System.EventArgs e)<br>
            this.Application.PresentationNewSlide +=<br>
               new PowerPoint.EApplication_PresentationNewSlideEventHandler(<br>
<p>        void Application_PresentationNewSlide(PowerPoint.Slide Sld)<br>
            PowerPoint.Shape textBox = Sld.Shapes.AddTextbox(<br>
                Office.MsoTextOrientation.msoTextOrientationHorizontal, 0, 0, 500, 50);<br>
            textBox.TextFrame.TextRange.InsertAfter("Property of Tim Dams");<br>


Like this tutorial? Feel free to buy my kids a fristi 


14 gedachten over “How to create a simple office VSTO add-in :A step by step guide

  1. Thank you for the tutorial. Quite straight forward and gave me the courage to experiment more 🙂


  2. 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.


    1. 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.


  3. Hello! how can I make this an installable application? thanks!


  4. I want only the highlighted texts to be selected. For e.g. “Hi, How are you ? I have not heard from you for a long time.”

    In the above sentence, suppose if the user selects only “How are you” and then clicks on the “Click Me” button, only the highlighted text which in this case is “How are you” should be populated.

    Is there any way to achieve this ?


  5. hi Tim, thanks for the blog. Helped me big time. Cheers.


  6. jantappenbeckjan september 6, 2019 — 08:05

    hi !

    a very interessting Artikel – because i want to create my first Outlook addin.
    i have a Little problem – could you tell me how to find the way?
    i want to save the current mail.

    Dim myItem As Outlook.Inspector
    Dim objItem As Object
    myItem = Globals.ThisAddIn.Application.ActiveInspector

    myItem.SaveAs(FullPathMsgFile, Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSGUnicode)

    i get an error, because the inspector would be not the Right way!


    reagards Jan


    1. What error do you get? Without any specific error-message it’s very difficult to discover what is going wrong. I think it’s best to post your problem on stack overflow in this case 😉


      1. Anirudh Challa juli 2, 2020 — 23:13

        Hi Tim,
        Thanks for this tutorial. It was very nicely explained. This has encouraged me to make more such addin’s. Can you guide me with the following scenario.

        I have inserted a button. On clicking the button a certain URL should be opened inside the outlook window. Currently while clicking the button a new browser window is getting opened.


  7. Could you please implement property change event?


  8. Tomasz Szkudlarek december 1, 2020 — 12:23

    Do you know if VSTO are gonna work in Outlook 2019?


  9. Eric Eskildsen juni 29, 2021 — 00:40

    The tip about RibbonType was a huge help. I was going through MS’s docs and couldn’t get it to show up. Much appreciated!


Geef een reactie

Vul je gegevens in of klik op een icoon om in te loggen. logo

Je reageert onder je account. Log uit /  Bijwerken )

Facebook foto

Je reageert onder je Facebook account. Log uit /  Bijwerken )

Verbinden met %s

Deze site gebruikt Akismet om spam te bestrijden. Ontdek hoe de data van je reactie verwerkt wordt.

%d bloggers liken dit:
search previous next tag category expand menu location phone mail time cart zoom edit close