This article is about an Outlook AddOn (VSTO) to store the attachments in the file system. This AddOn will be shown as a Pane integrated in Outlook, so the user is able to simply drag-drop the Email into the appropriate folder. The folder will be automatically selected based on the current Email address.
The goal of this project is to show how simple it is to create a custom pane in the Microsoft Outlook  and do some action based on the Email address of the current Email object:
This tool reads an address of current selected Email and shows in the pane on the right side the appropriate folders with its sub-folders.
Now, a user can easy drag-drop the Email in one of the sub-folders in order to save its attachment there.
The mapping between the Email addresses and the folders takes place in the configuration file, please take a look at OutlookAddOn.xml:
As you see, the address is separated from folder by pipe character like this:
<folder>Attachment_of_Emails_with_this_address ... | ... should_be_saved_in_sub-folders_of_this_folder</folder>
<folders> is a list of entries, user is able to add as many addresses as he needs.
The technique behind is the VSTO (Visual Studio Tools For Office). This API makes it possible to get all information of an Email object, for example, the count of attachments as well as the attachment itself.
Some registry entries are necessary when you deploy VSTO Add-ins that are created by using Visual Studio. These registry entries provide information that enable the Microsoft Office application to discover and load the VSTO Add-in .
When a VSTO Add-in is installed, it can be registered in two ways:
- For the current user only (that is, it is available only to the user that is logged on to the computer when the VSTO Add-in is installed). In this case, the registry entries are created under the
- For all users (that is, any user that logs on to the computer can use the VSTO Add-in). In this case, the registry entries are created under
This is an example of how to install Add-in for the current user:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Vsto Runtime Setup\v4]
You will need to replace the H:/_Projekte/OutlookAddOn/bin/Release/ with the path of the folder contained AddOn and to save this code snipped in a file *.reg. By executing this file (double click), all keys will be added to the windows registry:
How Outlook VSTO AddOn Works (Callbacks)
There are two important callback functions that are necessarily needed to get an AddOn working :
Startup method - a kind of constructor, a perfect place to create our custom form / pane:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
oUserCtrl = new axUserCtrl(this);
Explorer.SelectionChange event which will be fired every time an
Email item get selected:
private void CurrentExplorer_Event()
if (this.Application.ActiveExplorer().Selection.Count == 1)
Object selObject = Application.ActiveExplorer().Selection;
if (selObject is MailItem)
MailItem mailItem = (selObject as MailItem);
That is actually all that we need:
- We have created a custom form that will be shown as a pane embedded in Outlook, and
- We get a notification / callback every time the Email selection changed - the current Email item will be provided to the custom form!
One information that we need is the Email address to show an appropriated folder, the second information is the path to the attachment to store it into this folder.
Another important point is to use the worker thread wherever we do something in the background:
_workerThread = new Thread(_oWorker.GetResultList);
We should avoid the freezing of the GUI, otherwise our AddIn can be refused by Outlook.
Using the Code
axFileSystemWorker is derived from
axBaseWorker in order to show one of many possibilities, what can be achieved by using the VSTO interface:
enMode nMode = _oWorker.GetMode();
if (nMode == enMode.eFILE_SYSTEM)
_oWorker = new axFileSystemWorker(this) as iWorker;
We can easily implement a REST interface (
GET) or something else by deriving from
axBaseWorker and overriding the virtual methods, for example:
public virtual bool Connect()
throw new NotImplementedException();
Points of Interest