Logo
HOWTO: Removing commands and UI elements during Visual Studio .NET add-in uninstallation

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio .NET 2002
Date: June 2005   Microsoft Visual Studio .NET 2003
Updated March 2013   Microsoft Visual Studio 2005
      Microsoft Visual Studio 2008
      Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012
Introduction

This article describes how to delete commands and other permanent UI elements created by an add-in when it is uninstalled.

More Information

The commands created by an add-in should not be deleted when the add-in is unloaded, because it takes time to create them on each add-in startup and user customizations such as keyboard bindings would be lost. Instead, they should be removed when the add-in is uninstalled.

The user interface (buttons and commandbars) created by an add-in can be temporary or permanent, as explained in the article HOWTO: Adding buttons, commandbars and toolbars to Visual Studio .NET from an add-in. If the user interface is temporary, the add-in removes it when it is unloaded. But if the user interface is permanent, it must be removed when the add-in is uninstalled.

This article explains how to remove commands when the add-in is uninstalled. When a command is removed, the buttons that were created from that command using the Command.AddControl method are automatically removed. If the add-in creates permanent command bars, the same approach can be used to remove them on uninstallation.

To remove the commands of the add-in, its uninstaller must perform a custom action. To learn how to create a custom action, check the documentation of your uninstaller. For the purpose of this article, we will use a VB script (.vbs file extension) for a custom action. The custom action must perform the following steps:

  • Create an instance of Visual Studio .NET through its ProgID calling the CreateObject method:
    • "VisualStudio.DTE.7" for Visual Studio .NET 2002
    • "VisualStudio.DTE.7.1" for Visual Studio .NET 2003
    • "VisualStudio.DTE.8.0" for Visual Studio 2005
    • "VisualStudio.DTE.9.0" for Visual Studio 2008
    • "VisualStudio.DTE.10.0" for Visual Studio 2010
    • "VisualStudioDTE.11.0" for Visual Studio 2012

    This will return a DTE object which gives access to the extensibility model. That instance will remain invisible by default.
  • Retrieve the command(s) of the add-in using DTE.Commands.Item(commandFullName) and call the Delete() method on each one.
  • Close the instance of Visual Studio .NET, calling DTE.Quit() or DTE.ExecuteCommand("File.Exit").

There is an unfortunate bug in Visual Studio .NET 2002/2003, though. Commands (and permanent command bars) are persisted on disk in the file:

  • Windows XP: "C:\Documents and Settings\<user>\Application Data\Microsoft\VisualStudio\<version>\1033\CmdUI.PRF"
  • Windows Vista and higher: "C:\Users\<user>\AppData\Roaming\Microsoft\VisualStudio\<version>\1033\CmdUI.PRF"

where <version> is:

  • 7.0 for Visual Studio .NET 2002
  • 7.1 for Visual Studio .NET 2003
  • 8.0 for Visual Studio 2005
  • 9.0 for Visual Studio 2008
  • 10.0 for Visual Studio 2010
  • 11.0 for Visual Studio 2012

With the approach described so far, if the buttons created from commands of the add-in (created from commands using Command.AddControl) were added only to command bars created by the add-in (and not to built-in command bars of Visual Studio), it happens that when the commands are deleted the file is not marked as dirty and therefore although the uninstallation doesn't show any error, commands are not actually removed since that file is not updated. The workaround is to create at uninstallation time a button from the command on a built-in command bar of Visual Studio .NET such as the "Tools" menu.

The following VB Script sample shows the final code of the custom action with the workaround:

Language: VBScript   Copy Code Copy Code (IE only)
Dim objDTE
Dim objCommand
 
Set objDTE = CreateObject("VisualStudio.DTE.7.1")  ' Visual Studio .NET 2003

Set objCommand = objDTE.Commands.Item("MyAddIn.Connect.MyCommand")

' PATCH: add the command to the Tools menu
objCommand.AddControl(objDTE.CommandBars.Item("Tools"))
 
objCommand.Delete

objDTE.Quit;

Visual Studio 2005 and higher introduces a new handy /ResetAddin command-line flag for the devenv.exe application that can be used to remove the commands of an add-in and its associated permanent buttons. It doesn't remove the permanent commandbars created calling EnvDTE.Commands.AddCommandBar, though, because that method doesn't receive a parameter with the add-in instance, so Visual Studio doesn't know whether the owner of a permanent commandbar is an add-in to remove the commandbar when resetting its owner add-in.

The usage is the following:

devenv.exe /ResetAddIn Namespace.ClassName /Command File.Exit

where Namespace.ClassName is the full name of the Connect class. Since the IDE will remain open, /Command File.Exit is used to close it.

Since devenv.exe is not available from the normal MS-DOS command prompt, you will need to specify its full path, which can be retrieved from the Windows registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\<version> registry key, "InstallDir" value.

Where <version> is:

  • 8.0 for Visual Studio 2005
  • 9.0 for Visual Studio 2008
  • 10.0 for Visual Studio 2010
  • 11.0 for Visual Studio 2012

Finally, this command has no effect if the add-in is loaded when the IDE is loaded, so the uninstaller needs to unregister the add-in first, and then execute the command to remove the add-in commands. While the /SafeMode command-line flag could be used in Visual Studio 2008 or higher to prevent the loading of the add-in, it doesn't work in Visual Studio 2005 (see the article BUG: The /SafeMode command-line switch of Visual Studio 2005 doesn't prevent the loading of add-ins), so you must use the proper order in the steps of the uninstaller.

The "HOWTO: Create a setup for a Visual Studio add-in" articles below show how to remove commands during the uninstallation of an add-in.

Related articles


Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this


Top