Create Office add-ins: ribbons, toolbars, task panes, menus etc.
Starting from version 2000, Office applications allow COM add-ins to customize their user interface with toolbars, menus, context menus, ribbons, task panes etc. COM add-ins run within the process of their host application and use programmatic interfaces provided by the host in order to access currently open documents and modify their contents or react to user actions. Naturally, to be executed in this way add-ins should conform to some rules.
For the .NET developer, Office add-ins are class libraries implementing the IDTExtensibility2 COM interface and registered in an appropriate registry branch in HKEY_CURRENT_USER. To run for all users on the current PC, Office COM add-ins must be registered in HKEY_LOCAL_MACHINE. Obviously, this requires administrative privileges.
A number of other COM interfaces require implementation if your add-in customizes the Office 2007 Ribbon user interface (IRibbonExtesibility), creates custom task panes (ICustomTaskPaneConsumer), and so on. The user is allowed to enable or disable COM add-ins via COM Add-ins dialog:
How to start writing add-ins for Microsoft Office? What problems should you be aware of? How do you deploy the add-in? What tools are available?
Is it possible to write an Office add-in that will fulfill my task?
First off, you are to find out if the Office application you want to use as a host for your add-in provides the features you need. Here is one of the most frequently asked questions on the Add-in Express forum: Is it possible to add a custom page to the Tools | Options dialog in Excel? Our standard answer is: It is not possible because the Excel Object Model doesn’t provide any way for this.
However, where does an object model live? The best way to study any Office Object model is the Object browser available in the Visual Basic IDE. Having run the host application, you open the environment by choosing the Tools / Macro / Visual Basic Editor menu item or by pressing Alt + F11. Note that some Office applications, recent ones mainly, do not provide IDE. If it is the case, please refer to Programmer’s Reference or MSDN.
When in the IDE, you choose View / Object Browser in the menu or press F2. The Object Browser provides you with public classes, their properties and methods as well as with public enumerations for all object models that the currently open document refers to (use Tools | References to add a new reference). You can restrict the browser to show the public interfaces of a single object model: use the topmost combo to select, say Outlook, Word, Excel, or MSProject. The Object browser allows searching through any or all object models. There is a restriction though: it doesn’t search through a method’s parameters. When you find an object of interest, you click it and press F1 to get the help article related to this object. Those help articles are the shortest way to understanding of the object model.
The Object Browser reveals all the declarations in VBA syntax. If you have no or little experience in VB6 (VBA) programming, please note that some declarations don’t specify the types of parameters and/or return values. Consider the following declaration in the Word object model, note that this pattern is often used in other object models:
Function Item(Index) As Bookmark
It defines the Item function which returns a value of the Bookmark type. However, the declaration doesn’t reveal the type of the Index parameter. In such situations you should know that the Browser omits the Variant keyword. That is, the declaration above should read as follows:
Function Item(Index as Variant) As Bookmark
The Variant data type is a predecessor of the Object data type in .NET programming. Like Object variables, Variant variables can accept almost any data types. When you click the function above and press F1, it appears that the Index parameter can accept numeric and string values either the index position of the Bookmark in the Bookmarks collection or a bookmark’s name.
I understand that you may never have used (and will probably never use) VBA. However, I insist on using the Object Browser: it is the essential step of getting into the insight of the Object Model of any Office application.
To understand user interface options, you select Office in the topmost combo of the Object Browser. Here you find definitions of the types that all Office applications share: COM add-ins, command bars and controls, custom task panes, ribbons, etc.
What are the typical problems with Office add-ins?
If you’ve never done Office development before, you’ll be in a shock because while the user’s side of any Office application is remarkably stable and robust, the application’s object model is a completely different story. It’s like a minefield of bugs and issues: command bars behave differently in different Office applications or become disconnected suddenly, Outlook hangs in the Task Manager or doesn’t fire the events you rely upon, Office updates change the sequence of events, and many, many more. All this stuff increases the debugging time considerably.
Many problems arise on the .NET COM interaction area because .NET and COM differ in their strategies of object releasing. Blogs and newsgroups have a great number of questions like “Why Outlook is not closing?“. The problem has its name: Releasing COM objects in .NET. When releasing COM objects in a stand-alone .NET application, you are free to use any of the three approaches discussed by Andrew Whitechapel. Please note, these approaches are applied to standalone applications but not to add-ins. I’ll try to prepare some add-ins demonstrating the problems with using the approaches described in Andrew Whitechapel’s book. To make a long story short, COM add-ins developers have the only way. I’d call it the Bee Way: whenever you get a reference to a COM object, you must release it using the Marshal.ReleaseComObject method. You may think this will bloat your code sufficiently. However, this is the right way: you keep every aspect of your add-in under control. Here, at Add-in Express, we have a saying: Office overlooks mistakes for a very short period only.
The crucial question is: who will install your add-in? There are two possible answers: an admin or a standard user. If the admin installs your add-in, you have no problems when, say, your add-in requires to install its prerequisites. Note that some prerequisites are absolute musts: .NET Framework :), Windows Installer 3.1, Shared Add-in Support Update for Microsoft .NET Framework 2.0 (KB908002).
However, administrators are not inclined to participate in the add-in installation process: you can easily imagine installing an add-in on some two hundred PCs. In short, it is unpleasant for all sides of the process (you, the admin, and the user) to get the admin involved. The best practice is installing with non-admin permissions. To create such a setup you should know if the non-admin user has access rights to this or that folder / registry branch. Say, a standard user does not have access rights to Program Files and HKEY_LOCAL_MACHINE. If you know this, you target your setup project to the Application Data folder and HKEY_CURRENT_USER. In addition, you drop from your package every prerequisite that requires admin rights for installation.
The “non-administrative installation” theme has received its continuation in ClickOnce – a deployment technology introduced in .NET Framework 2.0. The name suggests that you can install some software in several clicks (let’s not waste time on trifles). When asked if COM add-ins can be installed with ClickOnce, Microsoft says no. Nevertheless, some clever guys in Add-in Express have found their own ClickOnce solution.
What are the tools?
You can create managed COM add-in using the following tools:
- Visual Studio 2003 & 2005 Shared Add-in Project Template
- VSTO 2005 or VSTO 2005 SE
- Visual Studio 2003 & 2005 with Add-in Express 2007 for Microsoft .NET.
Every tool differs in the functionality it provides as well as in the shim it uses.
Shims are unmanaged DLLs used to make Office load managed code. When you register your unmanaged add-in, the shim info gets written to the registry (instead of targeting the add-in assembly) for Office to load the shim whenever the add-in is to be loaded. Thus, the shim becomes an essential part of the add-in development in .NET since it:
- Loads the CLR
- Creates an AppDomain for your add-in
- Creates and caches instances of the managed COM add-in classes
- Redirects calls made into unmanaged classes to their managed counterparts
Shim comparison. Shared Add-ins are based on the universal shim installed with .NET Framework. It is called MSCOREE.DLL. VSTO add-ins are based on the VSTO Loader which is installed as part of VSTO run-time. The Add-in Express Loader is a custom shim that you install as part of your add-in installation. The Add-in Express Loader is configured via a manifest, it runs HKCU and HKLM targeted add-ins; it provides you with logging and allows installing the add-in when the previous version is being run. Also, note that Add-in Express supports the above-mentioned shims too. FYI, MSCOREE.DLL loads all Shared add-ins to the same AppDomain and in this way, one add-in can impede the work of other add-ins. In addition, you cannot sign it.
Office applications supported. All of the tools above support a number of Office applications. However, Shared Add-in and Add-in Express provide support for a broad set of Office applications (all Office versions), while VSTO confines itself to add-ins for Outlook 2003 only, and VSTO SE allows creating add-ins for 2003-2007 versions of Outlook, Excel, Word, PowerPoint, Visio, and for InfoPath 2007.
Office versions. Every tool allows developing for the currently installed Office version. Note, that every add-in developed for a given Office version will work for higher versions (with few exceptions). However, if you develop an add-in for Office 2003 in VSTO (VSTO SE), you will have to create another version of your add-in to access the features of Office 2007. Add-in Express provides Office 2000 interop assemblies. Thus, it makes possible to develop add-ins for Office 2000 no matter what Office version is installed on your development PC. What is more, your plug-ins developed with Add-in Express are version-independent, i.e. you write your code once and have the add-in work in all Office versions.
Setup. All of the tools above create an appropriate setup project automatically. However, with VSTO (VSTO SE) you will need to create custom actions for your add-in to get registered in .NET configs. With both VSTO and Shared Add-in you will have to configure your setup manually in order to allow non-admin installations. Note that Add-in Express simplifies and speeds up this part of add-in development: it allows choosing the installation type and provides ready-to-use custom actions.
ClickOnce. Shared Add-in doesn’t provide it. And as I pointed above, the VSTO ClickOnce wizard will not allow installing add-ins via ClickOnce. Add-in Express offers ClickOnce Solution that allows the end-user to install and update the add-in without the admin involved.
Development speed vs. flexibility. Shared Add-in and VSTO allow using all available Office interfaces and leave you face to face with them. The current Add-in Express version supports main interfaces only: COM add-in, Ribbon UI, and Custom Task Panes. To speed up the development, it provides components that solve typical problems of creating and using command bars (toolbars, menus, and context menus) and controls, Ribbon tabs, Office 2007 Menu, Quick Access Toolbar, custom task panes, keyboard shortcuts, as well as a number of Outlook’s oriented components: Explorer and Inspector command bars, Outlook Bar shortcuts, and property pages for the Tools | Options and Folder Properties dialogs. In addition, Add-in Express provides unique plug-ins that allow embedding custom .NET forms into Outlook windows and custom .NET controls into Office toolbars.
Of course, I’m a bit biased. Nevertheless, if I just say that I love Add-in Express for .NET, it will be close to nothing. Add-in Express allows me to create the user interface of my add-in in minutes. I never spend too much time to create an Outlook Explorer command bar: I drop a component on the AddinModule and specify its properties (its name is the most essential one) and events. To create a task pane, I just add a UserControl to my project and bind it to the TaskPanes collection of the AddinModule using a combo box. And so on, and so forth. The development speed on this stage is beyond any expectations. I used to program add-ins in VB 6 and I say: I could not even imagine that such things are possible.
Well, of course, it is possible to live without Add-in Express: you can google out many useful things about command bars and their oddities when using them in some Office applications. You can also find many interesting things about this or that situation with this or that Office application. Just think of the time you will waste if using the œmake-it-yourself scenario. Say, it is easy to add a command bar in Outlook explorer window (list of mails). However, you will have to foresee the command bar’s behavior in multi-explorer and no-explorer scenarios (when Outlook is run via Automation). Then you’ll find that the command bar (and custom controls) can become disconnected spontaneously. Then you will have to debug it in all Outlook versions you plan to support. Isn’t it too much work for just to show a command bar?
Support. Support is an integral part of all Add-in Express product packages. I guess you’d better see customers’ opinions yourself. Try to search for the following through the currently available posts on our forums:
- Search for excellent or great support
- Search for fast, quick or speedy support or response
- Search for next release or next build
A couple of useful links:
Andrew Whitechapel. Microsoft .NET Development for Microsoft Office. Selected chapters
When ReleaseComObject is necessary in Outlook
Microsoft: It is impossible to use ClickOnce for Office add-in deployment
Deployment of Managed COM Add-Ins in Office XP (contains additional info on shims)
Regards from Poland,
Add-in Express Team Leader