Creating an installer for Visio with WiX

If you develop add-ins, templates, or stencils for Visio, sooner or later you will face the question of how to deploy them. Visio allows you to deploy your solution or template in such a way that it can be embedded nicely in the Visio user interface, appearing like all other built-in Visio templates. For Visio developers, Visio SDK provides the Solution Publishing Tool, which is an official method to publish Visio-related components. However, this tool has several limitations, including:

  • It does not integrate well into automated build processes, such as when using continuous integration with a build server.
  • It uses custom VBScript actions, which may become a problem with some antivirus programs or in very restricted environments.

file

Windows Installer XML (WiX) builds Windows installation packages from XML source code and integrates seamlessly into build processes. The toolset originates from Microsoft, which used it internally to build Microsoft Office installers. The tool is highly robust!

This post explains the magic behind the Visio Solution Publishing tool and demonstrates how you can achieve the same result with WiX. It shows how to create an installer to install templates and stencils and includes a sample/template WiX solution to install Visio files for both Visio x86 and Visio x64.

Creating an installer involves the following steps:

  • Download and install WiX (version 3.6 was used for the sample project).
  • Create a WiX project in Visual Studio.
  • Add Visio template and stencil files to the project.
  • Customize the installer by adding Visio-specific actions (the most challenging part, which this post focuses on, as the other steps are relatively straightforward and well-covered in the user manual and numerous tutorials).

So, what does the Solution Publishing Tool actually do with the installer? It fills in the "PublishComponent" Windows Installer table and triggers Visio to rebuild the template cache by modifying the ConfigChangeID registry key. You can find more information about the table in this Microsoft KB832029 and this article. Since the Visual Studio installation project is a limited tool and does not support component publishing, this gap was filled by the Solution Publishing Tool.

WiX does not impose any restrictions and provides full access to all features Windows Installer supports. This means you can author these Visio publishing rules directly in the installer without the need for the Solution Publishing Tool, allowing your project to be built in Visual Studio or from the command line, including Azure DevOps, which supports WiX builds.

Adding Visio publishing information to the WiX installer

After adding a Visio template/stencil file, your WiX project will contain something like this:

<Component Id="StencilA">
  <File Name="StencilA.vss" />
</Component>

To publish the stencil to Visio, you need to add publishing information like this:

<Component Id="StencilA">
  <File Name="StencilA.vss" />
  <Category
    Id="{CF1F488D-8D6F-499C-A78D-026E1DF38101}"
    Qualifier="1033\StencilA.vss"
    AppData="X Stencils\Stencil-A" />
</Component>

The example above publishes an English stencil (ID = GUID of stencil), named "StencilA.vss", which should be made available under the category "X Stencils" as "Stencil-A". The field values for Visio are as follows (refer to the above KB article):

Attribute Value Example
Id Fixed code For templates: {CF1F488D-8D6F-499C-A78D-026E1DF38100}
For stencils: {CF1F488D-8D6F-499C-A78D-026E1DF38101}
Qualifier LocaleID\FileName 1033\flowchart.vst. Note: You cannot use multiples of the same file name in one Visio environment. Locale-ID\FileName must be unique so that Visio can recognize it. Therefore, use a unique file name in one Visio environment.
AppData MenuPath|AltNames Flowchart\Work Flow Diagram Shapes|Work Flow Diagram Shapes.vss;workflow.vss

Further description of values:

Value Description Example
ComponentID A predefined value for the content type. For templates: {CF1F488D-8D6F-499C-A78D-026E1DF38100}. For stencils: {CF1F488D-8D6F-499C-A78D-026E1DF38101}
LocaleID The decimal locale ID of the component. Common values include: 1033 (English), 1031 (German), 1036 (French), 1049 (Russian) 1033
FileName The file name (without the path) of the template or stencil flowchart.vst
MenuPath For templates, specifies where the template is displayed in the menus. For stencils, specifies where the stencil is displayed. An empty string means it won’t appear. If an underscore (_) precedes any name, it won’t show in menus. The final portion affects the Visio UI file name. Flowchart\Work Flow Diagram Shapes.
AltNames A semicolon-delimited list of alternate names. Overrides stored alternate names by the AlternateNames property of the Document object. Work Flow Diagram Shapes.vss;workflow.vss

Triggering Visio rebuild template cache

To inform Visio that new stencils/templates were installed, trigger a cache update by modifying the registry value ConfigChangeID under this key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Office\Visio.

The Visio Solution Publishing tool accomplishes this by embedding a small script to increase the ID by one:
Action "VisSolPublish_BumpVisioChangeId32"

Dim WshShell, visChangeId
Set WshShell = CreateObject("WScript.Shell")
Key = "HKLM\Software\Microsoft\Office\Visio\ConfigChangeID"
On Error Resume Next
visChangeId = WshShell.RegRead()
If Err = 0 Then WshShell.RegWrite Key, visChangeId + 1, "REG_DWORD"

With WiX, you can implement this in several ways:

  • Use the same method as the Solution Publishing tool by adding the following code to your installer:
<!-- define script action to increment Visio counter -->
<CustomAction
  Id="SetConfigChangeID"
  Script="vbscript"
  Execute="deferred"
  Impersonate="no"
  Return="check" >
<![CDATA[
    Set WshShell = CreateObject("WScript.Shell")
    Key = "HKLM\Software\Microsoft\Office\Visio\ConfigChangeID"
    On Error Resume Next
    visChangeId = WshShell.RegRead(key)
    If Err = 0 Then WshShell.RegWrite key, visChangeId+1, "REG_DWORD"
]]>
</CustomAction>

<!-- execute script action on install -->
<InstallExecuteSequence>
  <Custom Action="SetConfigChangeID" After="InstallInitialize" />
</InstallExecuteSequence>
  • Implement a custom action that does not involve scripting (see the sample solution for implementation details).

Two sample solutions have been attached for reference (templates) to build your installer. The first uses the VBScript approach (to bump ConfigChangeID with VBScript), while the second implements a custom action. The setup deploys 2 templates and 2 stencils.

https://unmanagedvisio.com/download/source/WixSolutionSetup.zip

https://unmanagedvisio.com/download/source/WixSolutionSetup_SC_Script.zip

The solutions should build an installer (x86 or x64 version depending on the selected configuration) to install templates and stencils in English and German under categories "X Stencils" and "X Templates". It should work with all Visio versions (2003 – 2013).

Installation Example

Map of Russia in Visio – version 1.0.1

Updated the recently published map:

  • Added related page to the with some pictures and video =)
    – Now all regions are stored alphabetically (yep, they were not)
    – Now you can install this template using installer (and it will show up in Visio templates – in category "Maps and Floor Plans".
  • Preview picture for the template enhanced using technique described here.

20-04-2013 22-41-20

Visio Map of Russia regions

Visio template containing all regions of Russia. The regions were designed to work as all other Visio-based maps (e.g. world map, europe map), and alike.

Each region shape in a stencil is equipped with shape-data which includes region name (in English and in Russian), region code, macro-region name, capital, and some other potentially useful fields. You can easily bind this to some data you have to build a nice diagram with external data, e.g. see examples below with "macro-regions" and "population".

You can use your custom data (e.g. from Excel file) to add some extra information to the map, e.g. to color it by region:

21-04-2013 9-48-17

Demo_VisioMap1.zip (746.1 KiB)

Also you can bind that data to shapes – e.g. I used excel file from the official site as "external data" to show population (also Visio theme applied):

21-04-2013 9-40-40

Demo_VisioMap2.zip (1.0 MiB)

Please check out also functions "Arrange to Page" and "Arrange to Shape" from the "world map" shapes.

After you drag the shapes you want to use onto the drawing page, you can arrange them to form a region as follows:

Press SHIFT and then click to select each of the shapes.
Right-click one of them, and then click Arrange To Page.

Visio will automatically place corresponding shapes together. If you want the map shapes to fill the entire drawing page, select the Size shapes to fill the drawing page check box. To add more shapes to a region:

  • Drag the additional shapes onto the drawing page.
  • Press SHIFT and then click to select each of the new shapes.
  • Right-click one of them, and then click Arrange To Shape.
  • On the drawing page, click a shape in the region that you want to align the new shapes to, and then in the Arrange To Shape dialog box, click OK

The map is available in 3 fashions – zip file with template/stencil and installer for Visio x86/x64.

FileDescriptionSizeDate
VisioMapOfRussia_20_04_2013.zip Maps of Russia regions (Visio template and stencil, in zip file)489.1 KiB20.04.2013
VisioMapOfRussia_20_04_2013_x64.msi Maps of Russia regions (Visio template and stencil, packed in installer for Visio x64)600.0 KiB20.04.2013
VisioMapOfRussia_20_04_2013_x86.msi Maps of Russia regions (Visio template and stencil, packed in installer for Visio x86)596.0 KiB20.04.2013
RussiaMapVisio_04_2012.zip RussiaMapVisio 04 2012914.3 KiB04.04.2013

Map of Russia in Visio

This is Visio map of Russia (year 2012). The map is in Visio VSD format. Includes a stencil with all regions as separate shapes and "assemled" sample drawing. The map was built to work nicely with the standard Visio "maps" functionality (like World Map), and additionally includes items which are specific to regions in Russia (region ISO code, capital, etc) as shape data. Download and details follow.

11-04-2013 20-16-22
Continue reading“Map of Russia in Visio”

Find Visio Command Addin

Have you ever tried to find a particular command in new Visio 2010 user interface? This was a little bit frustrating for me and I decided to develop a simple add-in which allows you to quickly find commands in Visio 2010. Just type in the keyword which is a part of command name, and hit enter. All commands which contain this keyword will be shown by the plugin as buttons. You can either use the command found directly from the results pane, or add it to the quick launch toolbar.

The big picture:

27-06-2011 4-57-14

Video:

http://www.youtube.com/watch?v=KJowDTZXihI

Using the same set of button images with transparency in all Visio versions

If you write a Visio add-in that targets multiple Visio versions at the same time, and have some custom buttons with images (with transparency), you might run into trouble with that new Visio 2010 Ribbon user interface needs different “flavor” of images compared to Visio 2003 and 2007. So you’ll have to to either create two separate sets of images (one set for pre-ribbon version of Visio, the second set for the ribbon one), or to “dance around a little” and make both versions consume the same set of images. The article focuses on the second approach I ended up with.

Continue reading“Using the same set of button images with transparency in all Visio versions”

Persisting Visio shapes

This article explains this post in microsoft.public.visio.developers newsgroup, and provides information on how one can to save Visio shapes in external source exactly, so here is the code to store master/shape in a stream and then drop it back to the document:

To save Visio shapes in some external system (persist them) you can:

– Query master or shape you want to persist for IDataObject interface.
– Using this interface, obtain data blob in “Visio 11 Shapes” clipboard format (or maybe actually anything that contains “Shapes” word to be compatible with further Visio versions, please refer to the code).

Now this blob can be stored any way you want (database/memory/file/whatever). The sample code just saves it to a string variable in base64 encoding. To drop shapes back to the drawing, you can use “Drop” functions of Visio document/page. It turned out that these functions are happy enough with plain IDataObject interface passed in. So, to drop the stored master or shape back to the drawing:

– Create you own object that implements IDataObject interface.
– Load this object with your data
– Pass this object in one of those “Drop” functions (e.g. Page.Drop)

Continue reading“Persisting Visio shapes”

Making the Visio ribbon tab document-dependent

This post explains how to make a ribbon tab in Visio 2010 ribbon document-specific. Means, activate a custom ribbon tab only for a specific document.

This article discusses the implementation of a document-specific tab in a COM add-in; also, it focuses on details you might be interested in if you e.g. program unmanaged C++. Note that you could create a custom document-specific ribbon by other means, e.g. by embedding your custom interface in a document template using new Visio 2010 property Document.CustomUI

Nevertheless, one of the ways to it is

Continue reading“Making the Visio ribbon tab document-dependent”