Deploy Customized ArcMap Toolbar Via WiX

Author:      Hao (Steven) Chen (
Language:    VB.Net 2008
Platform:    Windows, .NET 2.0, AcrMap 9.2
Technology:  .NET, ArcGIS, COM Interop, MSI, WiX

Source Code



This article demonstrates how to create an ArcMap toolbar and install it on the client computer.


ESRI ArcMap is the most popular GIS software in the world. A lot of users not only use the ArcMap, but also customize it to fit their business rules. ArcMap exposes its API through the ArcObjects, a COM based programming tools. So far, I find the best reference book for the ArcObjects shall be the “Exploring ArcObjects” by Michael Zeiler, even though it was written for the ArcGIS 8.0. Any languages that support COM can be used to develop an ArcObject application. ESRI supports the .Net programming technology through the COM interop. It means that all the customized toolbars, menus and commands developed by.Net have to be registered as a COM server before they can be used in an ArcMap session. The first part of this article will create an ArcMap toolbar assembly called “ArcMapToolBarDemo”.

The second part of this article will demonstrate how to install the customized toolbar on the client computer. InstallShield or Wise are both professional installation tools. But they are very complex and expensive to a beginner. One good choice will be the Windows installer XML (WiX). It is an open source tool and offers very advanced features to author the windows installation package. The following links provide a Wix tutorial:

Using the Code

The "Demo prject" is an MSI file that install a sample ArcMap toolbar ("CHH Toolbar Demo") on the client computer. To use this demonstration, the client computer has to pre-install following software: .Net framework 2.0 and ArcMap 9.2 with service pack 6. After first installation, open the ArcMap and click the menu ‘Tools’ and ‘Customizes’. In the toolbar list, the user will see the toolbar.

The source code solution includes two projects, one ArcMap toolbar project called ArcMapToolBarDemo, another the WiX project called WixProject1. To open and compile the solution, the developer computer has to pre-install following software: Visual Studio 2008 Professional Edition, Windows Installer XML 3.0 and ArcMap 9.2 with service pack 6.

The source codes can also be imported to Visual Studio 2005 and recompiled with ArcGIS 9.1.

Create ArcMap Toolbar

Please refer to the source codes. Here we only list a couple points of interest when creating an ArcMap toolbar dll:

1. The project needs at least two references: ESRI.ArcGIS.Framework and ESRI.ArcGIS.SystemUI

2. ArcMap uses COM interoperation to communicate with a .Net dll. So, each ArcMap command, menu or toolbar shall be equivalent to one COM class file in the .Net project. In the sample code, there are three COM class files called “GISToolBar”, “Menu1” and “MenuItemDemo”.

3. When adding a COM class file via the Visual Studio “Add New Item” wizard, the visual studio will automatically add three GUIDs (ClassID, InterfaceID and EventID) to the COM class file. The “CLASSID” and “INTERFACEID” will be used in the WiX installation project.

4. In order to interoperate with the ArcMap, each COM class has to implement one or more ArcObject interfaces. Here is the common ArcMap UI interfaces:
    ArcMap toolbar shall implement IToolBarDef interface
    ArcMap root menu shall implement IRootLevelMenu and IMenuDef interface
    AcrMap menu item or ArcMap command shall implement ICommand interface.

5. ArcMap toolbar project shall check the “Register for COM interop” property, in order to ask the Visual Studio to generate an Interop Type Library (.tlb) at the output folder when building the project.

6. After build the solution, there shall be at least two files in the ArcMap toolbar project “Bin\Release” folder: ArcMapToolBarDemo.dll and ArcMapToolBarDemo.tlb. These two files will be packaged by the WiX project and installed to the client computer.

Create WiX Installation Package

There is an introduction article about the WiX 3.0. You can find another good sample here. Both of them provide a very detail explanation about the WiX syntax. In this article, we will only focus on how WiX register the COM class on the client computer.

When you check the  “Register for COM interop” property in the Visual Studio, the visual studio will call the Regasm.exe to register the COM classes. There is an Delphi article describing how the Regasm.exe register the .Net dll as COM server. Basically, the Regasm.exe will create a Type Library (.tlb) file for the .Net dll and add some keys and values into the computer registry table for each COM class. The WiX project will do the same work as the Regasm.exe does.

1. At the beginning of the WiX file, we define some variables. The first two are the ArcMap MxCommandBar and MxCommand category class ID.

<?define ESRIMxCommandBars_ClsID = "{B56A7C4A-83D4-11D2-A2E9-080009B6F22B}" ?>
<?define ESRIMxCommands_ClsID = "{B56A7C42-83D4-11D2-A2E9-080009B6F22B}" ?>

Each ArcMap toolbar, root menu, menu item and command shall implement one of these categories. Here is the list of the ESRI common component categories.

2. We also define a variable for each COM class ID and interface ID. You can get this GUID from each class source code file.

<!– Class ID—>
<?define ToolBar_ClsID = "{72CB06AB-5BE9-434e-90B0-8EB8A1AA60ED}"
<?define Menu1_ClsID = "{53bed23e-75ef-4787-9b4d-3c432239af47}"
<?define MenuItemDemo_ClsID = "{2c7bbfc0-19ea-4aee-86bb-eaad08b356e5}" ?>

<!—InterfaceID –>
<?define ToolBar_InfID="{6C762122-1F1B-4248-8E03-58844A2B7058}"
<?define Menu1_InfID="{dfc27c0b-46c5-4d6d-bef9-13750e79917f}"
<?define MenuItemDemo_InfID="{f0c30773-fb12-44eb-ad64-57ab6a0f79f6}"

3. Another group of variables define the COM class ProgID. Each ProgID is typically the COM class fully qualified name string, such as AssemblyDLLName.ClassName.


ProgID –>
<?define ToolBar_ProgID="ArcMapToolBarDemo.GISToolBar" ?>
<?define Menu1_ProgID="ArcMapToolBarDemo.Menu1" ?>
<?define MenuItemDemo_ProgID="ArcMapToolBarDemo.MenuItemDemo" ?>

4. On the client computer, the program install path will be “Program Files\Transviron\ArcMapToolBarDemo\Bin\”.

<!– Install Directory Hierarchy –>
<Directory Id="TARGETDIR" Name="SourceDir">
   <Directory Id="ProgramFilesFolder">
<Directory Id="CompanyFolder" Name="Transviron">
<Directory Id="InstallFolder" Name="ArcMapToolBarDemo">
<Directory Id ="BinFolder" Name ="Bin" />

5. Tow files, ArcMapToolBarDemo.dll and ArcMapToolBarDemo.tlb, will be copied to the aforementioned "BinFolder".

<Component Id="ArcMapToolBarDemo.dll" Guid="D27DBA2C-BACD-4861-AE41-478DBD2948FE">
<File Id="ArcMapToolBarDemo.dll" Name="ArcMapToolBarDemo.dll" KeyPath="yes"
         Source="..\ArcMapToolBarDemo\bin\Release\ArcMapToolBarDemo.dll" />


<Component Id="ArcMapToolBarDemo.tlb" Guid="45D13EB0-A8BD-4291-90E7-2F579652FBF0">
<File Id="ArcMapToolBarDemo.tlb" Name="ArcMapToolBarDemo.tlb" KeyPath="yes"
</File >
</Component >

6. Following registry keys shall be added for each COM class in the ArcMapToolBarDemo.dll.

HKCR\ProgID\(Default)= "{ProgID}"
HKCR\CLSID\{CLSID}\InprocServer32\Assembly=".Net Fully Assembly Name"
HKCR\CLSID\{CLSID}\InprocServer32\RuntimeVersion="NetFramework Runtime Versioin"
HKCR\CLSID\{CLSID}\InprocServer32\ CodeBase ="Assembly Install Location"
HKCR\CLSID\{CLSID}\InprocServer32\ Implement Categoriy ="{ESRI category ClassID}"


  • {ESRI category ClassID}, {CLSID} and {ProgID} are described as above.
  • ".Net Fully Assembly Name" shall be ArcMapToolBarDemo, Version=, Culture=neutral, PublicKeyToken=null. where the version can be "" if not in GAC.
  • "NetFramework Runtime Versioin" is the .NET framework version that the assembly refers to, here is v2.0.50727 for our example.
  • "Assembly Install Location" is where the assembly full file name with the full path name, that is the Program Files\ Transviron\ArcMapToolBarDemo\Bin\ArcMapToolBarDemo.dll for our example. If you put the assembly in GAC, this key will be ignored.

For example, following XML section will add these required registry keys for the "GISToolBar" COM class.

<Class Id="$(var.ToolBar_ClsID)" Context="InprocServer32" Description="ArcMapToolBarDemo GISToolBar Demo" ThreadingModel="both" Server ="ArcMapToolBarDemo.dll">
        <ProgId Id="$(var.ToolBar_ProgID)" Description="GISToolBar Demo" />
<RegistryValue Id=RegistryDLL_002 Root="HKCR" Key="CLSID\$(var.ToolBar_ClsID)\InprocServer32" Value="mscoree.dll" Type="string" Action="write" />
<RegistryValue Id=RegistryDLL_003 Root="HKCR" Key="CLSID\$(var.ToolBar_ClsID)\InprocServer32" Name="Class" Value="$(var.ToolBar_ProgID)" Type="string" Action="write" />
<RegistryValue Id=RegistryDLL_004 Root="HKCR" Key="CLSID\$(var.ToolBar_ClsID)\InprocServer32" Name="Assembly" Value="ArcMapToolBarDemo, Version=, Culture=neutral, PublicKeyToken=null" Type="string" Action="write" />
<RegistryValue Id=RegistryDLL_005 Root="HKCR" Key="CLSID\$(var.ToolBar_ClsID)\InprocServer32" Name="RuntimeVersion" Value="v2.0.50727" Type="string" Action="write" />
<RegistryValue Id=RegistryDLL_006 Root="HKCR" Key="CLSID\$(var.ToolBar_ClsID)\InprocServer32" Name="CodeBase" Value="[#ArcMapToolBarDemo.dll]" Type="string" Action="write" />
<RegistryValue Id=RegistryDLL_007 Root="HKCR" Key="CLSID\$(var.ToolBar_ClsID)\Implemented Categories\$(var.ESRIMxCommandBars_ClsID)" Value="" Type="string" Action="write" />

where, [#ArcMapToolBarDemo.dll] is the FileID of the assembly, and will point to the assembly file path on the client computer.

After installation, the registry will look like this for the "GISToolBar" class:

And InprocServer32 key has following values:

7. We also need to register the COM interfaces from the Type Libarary file (ArcMapToolBarDemo.tlb)


TypeLib Id="{b88cae70-b513-463d-a2df-2842ff2c760b}" Description="ArcMap ToolBar Demo" HelpDirectory="BinFolder" Language="1033" MajorVersion="2" MinorVersion="0">
<Interface Id="$(var.ToolBar_InfID)" Name="_GISToolBar" ProxyStubClassId="{00020424-0000-0000-C000-000000000046}" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
<Interface Id="$(var.Menu1_InfID)" Name="_Menu1" ProxyStubClassId="{00020424-0000-0000-C000-000000000046}" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
<Interface Id="$(var.MenuItemDemo_InfID)" Name="_MenuItemDemo" ProxyStubClassId="{00020424-0000-0000-C000-000000000046}" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
</TypeLib >

where, TypeLib ID is derived from the ArcMapToolBarDemo.dll project AssemblyInfo.vb file.

After building the WiX project, a windows installer package file (ArcMapToolBarDemo.msi) will be produced at the "Bin\Release" folder. The end user can use this msi file to install the customized ArcMap toolbar.


This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)

This entry was posted in ArcGIS. Bookmark the permalink.

4 Responses to Deploy Customized ArcMap Toolbar Via WiX

  1. scott says:

    Thanks for this article, it helped me out a lot as I found it very difficult to find information on correctly registering an arcmap toolbar in COM. I now have my weed & pest management toolbar registering correctly thanks to this article, which is a great end to three weeks of pain.

  2. Pingback: Replicating Visual Studio COM registration with a WiX Installer | Ask & Answers

  3. Pingback: Replicating Visual Studio COM registration with a WiX Installer | Technology & Programming

  4. Pingback: Replicating Visual Studio COM registration with a WiX Installer | Questions

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 )

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s