管理你的Visual Studio Toolbox

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

原文链接

The Most Complete Guide to Visual Studio Toolbox Control Integration

Libor Tinka, Lead Developer, ComponentOwl.com

管理你的Visual Studio Toolbox

Contents

1. Introduction
2. Prerequisites
3. Creating a Sample Control
4. Manual Toolbox Integration
5. Toolbox Integration using TCI
6. Toolbox Integration using DTE
7. Toolbox Integration using VSI Packages
8. Toolbox Integration using VSPackages
9. Toolbox Integration using VSIX Packages
10. Supporting Multiple Version of .NET Framework
11. Sample Source Code

1. Introduction

This tutorial is intended for developers who would like to distribute their WPF or WinForms controls and automatically put them into Visual Studio Toolbox during installation.

I struggled with Toolbox integration earlier because there are several possible approaches (harder to decide between them). Each approach have its own pros and cons and no overall comparison is provided. I wrote this tutorial to shed some light on the topic and spare you hours, maybe days of research and experimenting with aspects of Visual Studio (Toolbox) extensibility.

We will first take a look on Toolbox control integration in general to get a big picture. Each approach will be then discussed in detail and the following question will be answered:

  • How to install control in Visual Studio Toolbox?
  • How to update the control?
  • How to uninstall/remove the control?
  • How to support multiple Visual Studio versions?

There are several options on how to integrate your controls with Visual Studio Toolbox:

  • Manual installation
  • Toolbox Control Installer (TCI)
  • Visual Studio Automation Object Model (DTE)
  • VSPackage
  • VSI package
  • VSIX package

Manual installation

The simplest way of adding control into Visual Studio Toolbox is from within the IDE.

This approach have one crucial drawback, which is that you leave Toolbox integration to the user. Many developers are not that experienced with Visual Studio and when your component is shipped, even if you provide appropriate step-by-step guide, they may find it too complicated and rather try another component which "just works". I thought that every developer using Visual Studio is experienced enough to know how to add new items in VS Toolbox, but I received few e-mails from users who uninstalled the product just because the component have not appeared in the Toolbox and they thought it is broken (without reading our documentation, of course). On the other hand, there is a group of users who are not experienced developers, but are in charge of trying some products in a given company (e.g. project managers). These people can install the component, play with it and they would really appreciate if it just works. This increases chance they will actually purchase your product.

Advantages: zero effort
Disadvantages: require experienced users, slows user producitivity, updating controls is not intuitive

Toolbox Control Installer (TCI)

Visual Studio 2005 SDK contained a VSPackage called Toolbox Control Installer. This package comes pre-installed with Visual Studio 2008 and newer. Its job is to simplify the specific task of extending Visual Studio Toolbox. This approach requires you to install your assembly in GAC (Global Assembly Cache) and create a key in Windows Registry.

Advantages: simple and fast component installation, updating and removing
Disadvantages: requires installation in GAC (not always wanted), VS 2005 supported with SDK only

Visual Studio Automation Object Model (DTE)

If you are not afraid of COM, you can try DTE (Development Tools Environment) approach. There is already a project on CodePlex called Visual Studio Toolbox Manager, which solves the toolbox integration problem using a simple command-line application. The project is outdated since it does not support Visual Studio 2010 and newer. I made a project called DteToolboxInstaller, which is also a command-line application and does support Visual Studio 2013, 2012, 2010, 2008 and 2005. You can use the project as you like. The main disadvantage of DTE approach is the speed. The installer have to run devenv.exe using the automation interface, create a fake VS Solution, open Toolbox, add the stuff and then close the Solution. The whole process take no less than 10 seconds. If you want to integrate with two or three versions of Visual Studio, it can take well over a minute.

Advantages: does not require updating registry or GAC, full control over Toolbox
Disadvantages: very slow, separate installation required for every version of Visual Studio

VSPackage

A VSPackage seems to be a natural option. VSPackages allow any type of Visual Studio extension and you can manipulate Toolbox as well. There was a trouble with VSPackages in providing a Package Load Key (PLK) which can be generated only manually using web form. The requirement for PLK vanished with Visual Studio 2010 (hooray!). The nice thing about VSPackage approcach is that it does not slow down the installation process. The package is loaded and the controls are installed on-demand (when the Toolbox is opened for the first time after installation). After trying all the approaches, using VSPackage seems to be fastest and most universal one.

Advantages: quick installation, appearance in About box and other extensibility features
Disadvantages: cmplicated setup, each component requires its own package if shipped separately

VSI Package

VSI packages are quite old but you can use them for integration with Visual Studio 2005 and newer. It have very simple structure and you can create one even without Visual Studio. The only trouble with VSI compared to other approaches is invoking a wizard form which cannot be suppressed. The installation just cannot run in "quiet" mode. Another trouble with VSI is that a digital signature is required in order to get rid of a warning dialog. Your control will be always installed under "My Controls" tab in the Toolbox, which is not always desirable.

Advantages: simple creation, installer provided by Visual Studio, automated creation and signing requires several specific steps
Disadvantages: no quiet mode (extra steps when custom installer is used), manual uninstallation

VSIX Package

VSIX packages came with Visual Studio 2010 so you can integrate with 2010 or newer. the .VSI and .VSIX file extensions are associated with Visual Studio so you can simply double-click it or run it via shell. You can also run VsixInstaller.exe utility that performs the installation. Good news: No more nag screens when VSIX is not signed - the installer only contains a dialog with simple text: "This extension does not contain a digital signature." Even better news: The VsixInstaller supports quiet mode!

Please note that VSI and VSIX package installers contain features like displaying EULA, choosing which components to install or localization. When deploying your controls for use in Visual Studio, you won't need an installer on top of the package.

Advantages: installer provided by Visual Studio, quiet mode, fast installation
Disadvantages: package project required, automated creation is complicated, no support for VS 2005 and 2008

Comparison of Approaches

Here is a table summarizing features of the discussed approaches. As you can see, the VSPackage approach gives you the most freedom, but is also hardest to implement. We will discuss every approach so that you will be able to impement the one that suits you best.

  2005 2008 2010 2012 2013 Speed Install Automation Uninstall automation 
Manual installation 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox depends on user 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox
TCI 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox fast 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 
EnvDTE 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox slow 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 
VSI 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox moderate 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 
VSIX 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox moderate (faster than VSI) 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 
VSPackage 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox fast 管理你的Visual Studio Toolbox 管理你的Visual Studio Toolbox 

2. Prerequisites

We will focus on integration with Visual Studio 2010, 2012 and 2013. Hence you will need:

  • Visual Studio 2010 (or 2012, 2013)
  • Visual Studio 2010 SDK (or 2012 SDK, 2013 SDK)
  • Microsoft Windows SDK

The VS SDK contains regpkg.exe tool and project templates discussed in VSIX and VSPackage approaches.

The Windows SDK contains gacutil.exe, guidgen.exe, signtool.exe and other useful tools.

There are two kinds of versioning used for Visual Studio. One is based on the release name (e.g. Visual Studio 2008) and the other is a classic version number (e.g. 8.0). Both will be used, so it should be noted which version numbers correspond to which versions of Visual Studio:

Release name Version number
Visual Studio 2005 8.0
Visual Studio 2008 9.0
Visual Studio 2010 10.0
Visual Studio 2012 11.0
Visual Studio 2013 12.0

3. Creating a Sample Control

We will start by creating simple WinForms control for integration in VS Toolbox.

You can start with File - New - Project... (Control+Shift+N) and select Windows Forms Controls Library template.

Of course, you can also create empty Class Library project, add references to System.Drawing and System.Windows.Forms and create a new control. In fact, any DLL containing public classes derived from Control will suffice.

We want to support .NET Runtime version 4.0 and 4.5, so the control should be built against .NET 4.0 to ensure compatibility (the lower framework version you use, the wider range of compatible frameworks since they are backward compatible). It should be noted that .NET 4.5 is an in-place update of .NET 4.0 and hence the 4.5 assemblies will work on machines with 4.0 runtime installedunless you use some feature specific to 4.5.

If you have multiple controls in your assembly and don't want to use some of them in Toolbox, decorate them with ToolboxItem attribute with defaultType parameter set to false:

[ToolboxItem(false)]public class InvisibleControl : UserControl{  ...}

I have created a very simple control called SampleControl:

管理你的Visual Studio Toolbox

Finally, I set version of the assembly 3.3.0.0 (I chose just something else than 1.0.0.0 to see where the specific version number appears).

Custom Transparent Icon for the Toolbox

Icons for Toolbox are 16 by 16 pixel images. Various image formats are supported (BMP, JPEG, PNG and ICO). However, you need to create 256-color BMP image to ensure transparency. The transparent color is determined by bottom left pixel of the icon. Transparency works for magenta (#ff00ff):

管理你的Visual Studio Toolbox

The icon file should have same name as the control class (i.e. SampleControl.BMP).

Finally, use ToolboxBitmapAttribute to link icon with the control class:

[ToolboxBitmap(typeof(SampleControl), "Resources.SampleControl.bmp")]public partial class SampleControl : UserControl{ ...}

Note that icon location matters, at least in C#. Since I have added the icon under custom folder namedResources, I need to reference Resources.SampleControl.bmp instead of justSampleControl.bmp.

Here is the resulting transparent icon in Toolbox:

管理你的Visual Studio Toolbox

Marking the Control as Toolbox Item

We can mark control as toolbox item by adding a ToolboxItemAttribute with defaultType parameter set to true:

[ToolboxItem(true)]public partial class SampleControl : UserControl...

This decoration is optional since the controls within assembly are considered toolbox items by default. However, we can mark certain control classes with ToolboxItem(false) to hide them from Toolbox. This comes in handy when we have multiple projects and there are too many controls in the Toolbox because loaded from all the other projects.

Signing the Assembly

The assembly containing controls (SampleControl.dll in our case) should be strongly named if we want them installed in GAC (Global Assembly Cache) later on. This is optional in most cases, but the Toolbox Controls Installer approach requires the assembly being installed in GAC, hence the strong name is necessary there.

To give an assembly a strong name, open project properties and find Signing tab:

管理你的Visual Studio Toolbox

Check the "Sign the assembly" option and select "<New...>" from the combo box. This will create a new .SNK file in your project which will be used to sign the assembly. You can also browse for existing key file. If you want to distribute multiple assemblies with custom controls, it is a best practice to use same strong name key for each assembly (it is possible to have one .SNK file located in Solution folder and put just a link to that file in each project; when we browse for the key under the Signing tab, the link will be used without copying the file).

The SNK (Strong Name Key) file is basically a private key to digitally sign your assembly. There is also a public key which can be used to verify the assembly and its shorter variant called "public key token" for assembly identification.

4. Manual Toolbox Integration

Installing

To install component into Visual Studio Toolbox manually, open some form or control in designer, open the Toolbox window (Control+Alt+X), right-click on the Toolbox window and select "Choose Items...":

管理你的Visual Studio Toolbox

The "Choose Toolbox Items" dialog will show up:

管理你的Visual Studio Toolbox

You can browse for DLL file with your component by clicking the "Browse..." button.

This is the simplest way of putting component in the Toolbox without extra actions required.

This can be unpleasant for end-users since it means many clicks they have to perform. I will explain how to integrate a component a little bit more so that it will be visible under the ".NET Framework Components" tab in the above dialog box and possibly show up in Toolbox automatically without extra effort of the user.

Making the Control Visible in "Choose Toolbox Items" Dialog Box

As you can see on the above picture, the SampleControl component is already displayed in the dialog box under ".NET Framework Components" tab.

This is because the folder containing our control is registered as "assembly folder" in the registry and hence is searched when the above dialog is populated.

You can register your own assembly this way by creating a key in registry:

32-bit OS: HKLM\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\<your control name>64-bit OS: HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AssemblyFolders\<your control name>

You can also create key for specific version of .NET runtime (this comes in handy if you distribute different components for different versions of .NET):

32-bit OS: HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\<your control name>64-bit OS: HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\<your control name>

In both cases, the default value for the key is a string with full path to the folder with your assembly.

You can specify Toolbox tab in which the component should show up by adding subkey named "Toolbox" with single string value "TabName" this value has Toolbox tab name as data. When you add such control in the Toolbox, it will reside under new tab with the specified name:

管理你的Visual Studio Toolbox

The control should also appear in "Choose Toolbox Items" dialog box if it is installed in Global Assembly Cache.

The control pops up in the Toolbox automatically in its own tab in Visual Studio 2012/2013.

Installing the Control in GAC

The benefit of GAC (Global Assembly Cache) is that the user needs not to browse for your control. He will just select it form the above dialog box without having to know where it is actually installed (the dialog is populated by controls from "assembly folders" and from the GAC).

The GAC have one useful feature and disadvantage at the same time: It allows holding multiple versions of the same assembly. When user makes reference to your control from GAC and set "Specific Version" to true in Reference Properties window, it will be tied to that version. When you install an "update", a new version will be added to GAC, but the user will stay with the older one. Of course, the "Choose Toolbox Items" dialog will show both versions, so the user can just replace old reference with the new one.

You can make the installer removing any older versions from GAC during installation and add/keep just the newest one. This will force the user to replace the reference since it breaks the build.

You can work with GAC by using tool called gacutil.exe or from code. We will discuss both approaches.

The gacutil.exe is located in Microsoft Windows SDK directory. There are two such extecutables:

c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\gacutil.exec:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe

The former is for .NET Framework up to version 3.5. The latter is for .NET 4.0 and higher. This is for compatibility reasons as a separate GAC have been introduced with .NET 4.0.

You can install an assembly to GAC by calling:

gacutil.exe /i SampleControl.dll

To uninstall it, we refer to our assembly by its assembly name, not file name:

gacutil.exe /u SampleControl

Finally, you can check if the assembly is installed in GAC by listing any instances of the provided name:

gacutil.exe /l SampleControl

It is not wise, however, to use gacutil.exe from a custom installer as it is located in SDK that user might not have installed. Furthermore, the SDK license does not allow bundling gacutil.exe with your installer.

Some installers like Inno Setup or MSI allow installing in GAC anyway.

You can also work with GAC using System.EnterpriseServices.Internal.Publish class. The class have two methods: GacInstall and GacRemove. Both methods take just path to assembly file as a parameter, so for example:

(new Publish()).GacInstall(assemblyPath);

will install the specified assembly in GAC.

Updating

Updating the control depends on how it is installed and referenced.

If you have added component in the Toolbox manually via "Choose Toolbox Items" dialog box and "Browse..." button, i.e. as a file reference, the default property of such reference is that it simply points to the specified file no matter which version it have (unless user sets "Specific Version" to true in reference properties window; the default is false in this case). Simply replacing the DLL with the control by a newer file will suffice. If the user have specified "Specific Version" to true, the build will break because the reference is no longer valid. He needs to replace the reference by a new one pointing on the same file which now have newer version.

If you have added the component from GAC (these components also appear in the "Choose Toolbox Items" dialog box), the "Specific Version" property of the reference is true by default:

管理你的Visual Studio Toolbox

This means that even if you install a newer version of the component in GAC, the project will still reference the older version and both versions will reside in GAC.

If you remove all versions of the component from GAC (e.g. using gacutil.exe) and then install just the newest one, the build will break unless the user changed "Specific Version" property to false.

Removing

Removing the manually installed control consists of just reverting all the steps done during the installation.

In case of file references, deleting the file is sufficient.

In case of tighter integration (GAC, registry), the registry keys need to be deleted and the control can be removed from GAC (e.g. using gacutil.exe).

Resetting Toolbox and Clearing the Toolbox Cache

The Toolbox can fall into state where it does not display some items, some are duplicate and some can be disabled. Sometimes the only remedy is to let Visual Studio rebuild the Toolbox from scratch.

To do that, right-click on the Toolbox window and select "Reset Toolbox". Visual Studio will go through all the installed packages and reloads components into the Toolbox.

If this won't help, you can perform hard reset of the Toolbox. Exit Visual Studio and delete all .TBD files in the following folder:

\Users\<user>\AppData\Local\Microsoft\VisualStudio\10.0\

It should be up to four files:

管理你的Visual Studio Toolbox

Once removed, start Visual Studio again. After showing the Toolbox, all items should load instead of loading only the cached versions.

5. Toolbox Integration using TCI

Installing

Toolbox Control Installer is a VS package pre-installed in Visual Studio 2008 and newer. It looks in Windows registry for components and loads them in the Toolbox.

Before using TCI, one can check if it is installed in the given version of VS. For example, the following registry key should exist if the Visual Studio 2010 have TCI installed:

32-bit OS: HKLM\SOFTWARE\Microsoft\VisualStudio\10.0\Packages\{2c298b35-07da-45f1-96a3-be55d91c8d7a}64-bit OS: HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Packages\{2c298b35-07da-45f1-96a3-be55d91c8d7a}

The TCI package GUID is always the same so you can make the check for any version of Visual Studio with the above key (only change the version number from 10.0 to corresponding version number, of course).

The only prerequisites for the assembly is that it should have strong name (i.e. to be signed). See section "Creating the Sample Control" for more information.

The installation consists of putting the control in GAC (see previous section for more information) and creating registry keys.

Suppose we have the SampleControl installed in GAC:

管理你的Visual Studio Toolbox

We will make reference to this assembly from registry by creating the following key:

32-bit OS: HKLM\SOFTWARE\Microsoft\VisualStudio\10.0\ToolboxControlsInstaller\SampleControl, Version=3.7.0.0, Culture=neutral, PublicKeyToken=3cc4c7b61201d46c64-bit OS: HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\ToolboxControlsInstaller\SampleControl, Version=3.7.0.0, Culture=neutral, PublicKeyToken=3cc4c7b61201d46c

The default value for the key is the Toolbox tab name name you would like to have for the component(s), e.g. "Component Owl".

Installing in Visual Studio 2012 and 2013

One extra step is required to make this work in Visual Studio 2012/2013, which is adding the registry key also in its user config hive, i.e.:

HKCU\Software\Microsoft\VisualStudio\11.0_Config\ToolboxControlsInstaller\SampleControl, Version=3.7.0.0, Culture=neutral, PublicKeyToken=3cc4c7b61201d46c

for VS 2012. Use 12.0_Config for VS 2013.

Updating

Updating the component is very simple. Just modify the above registry keys by changing the version number.

Removing

To remove the component, delete the above registry keys. You should also remove the corresponding assembly from GAC.

Automating Integration with TCI using TciToolboxInstaller

I made a simple command-line application called TciToolboxInstaller which does all the described steps. The usage is simple:

TciToolboxInstaller.exe [install|uninstall] [vs2005|vs2008|vs2010|vs2012|vs2013] [tab name] [assembly path]

For example, if you like to install SampleControl.dll in Visual Studio 2012 Toolbox, just call:

TciToolboxInstaller.exe install vs2012 "Component Owl" SampleControl.dll

You can use quotes for the last two parameters if they contain spaces.

The TciToolboxInstaller project is contained in sample source code.

6. Toolbox Integration using DTE

Installing

The DTE (Development Tools Environment) approach does not require working with GAC or registry. It remotely manipulates Visual Studio Toolbox and adds/removes items as needed.

The whole installation is done from (managed) code using COM wrappers. It works in the following steps:

  • Check if an instance of Visual Studio is not running. If not, continue.
  • Retrieve an EnvDTE.DTE object corresponding to the version of Visual Studio we want to integrate with.
  • Create a "dummy" project using the DTE object
  • Obtain Toolbox window and ToolBox object from it.
  • Find or create ToolBoxTab object.
  • Add item in the Toolbox tab (ToolBoxTab.ToolBoxItems.Add).
  • Wait until current instance of Visual Studio stops running.

Here are some of the step/strongs in C# code - it is an excerpt from DteToolboxInstaller project provided in sample source code:

// obtain a DTE objectType typeDTE = Type.GetTypeFromProgID("VisualStudio.DTE.11.0");DTE dte = (DTE)Activator.CreateInstance(typeDTE, true);// create a temporary filestring tempFile = Path.GetFileNameWithoutExtension(Path.GetTempFileName());string tempDirectory = string.Format("{0}{1}", Path.GetTempPath(), tempFile);// create Visual Studio SolutionSolution4 solution = (dte.Solution as Solution4);string templatePath = solution.GetProjectTemplate(TemplateName, "CSharp");solution.AddFromTemplate(templatePath, tempDirectory, DummyProjectName, false);// get Toolbox windowWindow window = dte.Windows.Item(Constants.vsWindowKindToolbox);// get ToolboxToolBox toolBox = (ToolBox)window.Object;// get Toolbox tabToolBoxTab toolBoxTab = (GetToolBoxTab(toolBox.ToolBoxTabs) ?? toolBox.ToolBoxTabs.Add(this.tabName));// add new item under the Toolbox tabtoolBoxTab.ToolBoxItems.Add(assemblyName, this.assemblyPath, vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);// select the Toolbox tabtoolBoxTab.Activate();// cleanupdte.Solution.Close(false);dte.Quit();Marshal.ReleaseComObject(dte);// wait till Visual Studio turns off completelyif (IsVisualStudioRunning()){ Thread.Sleep(VisualStudioProcessTimeout);}

There are several obstacles on implementing the DTE approach.

First of all, we need to ensure that Visual Studio is not running during the installation - this is because we want messages sent to Visual Studio instance will arrive in the "invisible" one ran from our code and not the one which the user have currently opened.

Similarly, we would like to wait a while until the instance terminates after installation. This is necessary when integrating with multiple versions of Visual Studio when just a single instance have to be running at a time. Doing two installations too quickly in succession may cause the previous one to fail because a Visual Studio instance is still running.

The communication between our code and Visual Studio is mediated by OLE message filter which needs to be implemented. You can take a look on DteToolboxInstaller (see below) source code, where is a working installer implemented that uses this approach.

Updating and Removing

Since we have full control over the Toolbox with this approach, updating or removing items/tabs is done with the corresponding DTE objects.

Automatic Integration with DTE using DteToolboxInstaller

I made a simple command-line application called DteToolboxInstaller which does all the necessary steps and solves the deals with the discussed obstacles. The usage is simple:

DteToolboxInstaller.exe [install|uninstall] [vs2005|vs2008|vs2010|vs2012|vs2013] [tab name] [assembly path]

For example, if you like to install SampleControl.dll in Visual Studio 2012 Toolbox, just call:

DteToolboxInstaller.exe install vs2012 "Component Owl" SampleControl.dll

You can use quotes for the last two parameters if they contain spaces.

The DteToolboxInstaller project is contained in sample source code.

7. Toolbox Integration using VSI Packages

Let's consider you don't have a custom installer and want to distribute your components in some kind of simple extension package that Visual Studio understands.

Visual Studio contains an installer for so called VSI packages that will do the integration work for you. If you have Visual Studio installed, the .VSI extension is already associated with the Visual Studio Content Installer.

Creating the VSI Package

I have created an empty folder and copied SampleControl.dll in it. All that is needed to make a VSI package is to create a .VSCONTENT file, which is simply a XML file satisfying Visual Studio Content Installer schema:

<VSContent xmlns="http://schemas.microsoft.com/developer/vscontent/2005">     <Content>        <FileName>SampleControl.dll</FileName>        <DisplayName>SampleControl</DisplayName>        <Description>ComponentOwl.com SampleControl</Description>        <FileContentType>Toolbox Control</FileContentType>        <ContentVersion>2.0</ContentVersion>    </Content></VSContent>

The content is readable and pretty straightforward. The ContentVersion element can contain either "1.0" (support for Visual Studio 2005, 2008 and 2010) or "2.0" (support for Visual Studio 2008, 2010, 2012, 2013).

Now we zip the two files and rename extension of the archive to .VSI. We should end up with the following three files:

管理你的Visual Studio Toolbox

If you double-click the SampleControl.vsi, the Visual Studio Content Installer opens up. You can start the installer from command line as well:

32-bit OS: C:\Program Files\Common Files\Microsoft Shared\MSEnv\VSContentInstaller.exe SampleControl.vsi64-bit OS: C:\Program Files (x86)\Common Files\Microsoft Shared\MSEnv\VSContentInstaller.exe SampleControl.vsi

The installer have a form o wizard:

管理你的Visual Studio Toolbox

Signing the VSI Package

By default, the VSI package is not signed. This causes showing: "Publisher: Unknown" label on the first page of the installation wizard and an unpleasant dialog box later on:

管理你的Visual Studio Toolbox

To avoid this, you need to digitally sign the VSI package. Of course, you have to own a digital certificate (usually an X.509 certificate stored in .PFX file).

Because we cannot sign ZIP files, we need to convert the .VSI file (which is actually a ZIP archive with just an altered extension) to self-extracting archive that the Visual Studio Content Installer recognizes. There is a tool called MakeZipExe to do this task:

MakeZipExe.exe -zipfile:SampleControl.vsi -output:SampleControl-unsigned.vsi -overwrite

The MakeZipExe tool is located at Visual Studio's binary folder:

c:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\MakeZipExe.exe

The second step is signing the .EXE file using signtool.exe. You can find signtool.exe in Microsoft Windows SDK, i.e.:

c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\signtool.exe

Here is a sample usage of signtool.exe:

signtool.exe sign /du "http://www.componentowl.com/sample-control" /f certificate.pfx /p abc123 /t "http://timestamp.comodoca.com/authenticode" "SampleControl-signed.vsi"

When signed, the "Publisher" and "Information URL" labels are filled in the installer and no dialog box appears. The benefit of signing is obvious - your users will know they are installing trusted, possibly high-quality software and there is a higher chance of your software being used more widely (for example, the government sector usually require such certified software).

You can also add an EULA to your VSI package. This can be done by adding a comment metadata in the archive by ZIP archiver that supports such feature (e.g. WinZip).

Uninstalling the Control from Toolbox

As far as I know, the control cannot be removed from the Toolbox programmatically. You need to delete the control's DLL located at

c:\Users\<user>\Documents\Visual Studio 2010\Controls\

the same should be done for every version of Visual Studio installed.

In Visual Studio, right-click on Toolbox and select "Reset Toolbox". The component will not be found and disappear. Similarly, you can just delete the control from the Toolbox or select "Choose Items..." from context menu and untick the control there:

管理你的Visual Studio Toolbox 

Drawbacks of Using VSI Package

One drawback of using VSI package is that the installer runs every version of VS IDE you have installed and which is supported by the package. The form will disappear eventually, but it lowers user experience.

Another drawback is that when you want to update your control, the installer offers whether to rename, replace or skip the file (e.g. SampleControl.dll). User have to decide to update, which also slows down installation and requires user interaction.

You also cannot specify custom Toolbox tab. All controls are installed under "My Controls" tab:

管理你的Visual Studio Toolbox

8. Toolbox Integration using VSPackages

This approach brings full control over the integration and other benefits. The VSPackages are loaded on-demand, so the integration process won't slow down a custom installer.