SlideShare a Scribd company logo
Creating,	debugging	and	deploying	
extension	packages	for	Microsoft	Visual	
Studio	2005/2008/2010/2012
Author: Paul Eremeev
Date: 12.10.2012
Abstract
This article contains the overview of several different methods for extending Visual Studio IDE. The
creation, debugging, registration and end-user deployment of Visual Studio extension packages will be
explained in detail.
Introduction
The following series of articles is dedicated to the development of the extension package for Visual
Studio 2005/2008/2010/2012 IDEs utilizing .NET framework and C# programming language. The
following topics will be covered:
• basic information on creating and debugging of MSVS plug-ins and maintaining these
extensibility projects for several versions of Visual Studio inside a common source code base;
• overview of Automation Object Model and various Managed Package Framework (MPF) classes
• extending interface of the IDE though the automation object model's API (EnvDTE) and MPF
(Managed Package Framework) classes with custom menus, toolbars, windows and options
pages;
• utilizing Visual C++ project automation model for gathering data needed to operate an external
preprocessor/compiler, such as compilation arguments and settings for different platforms and
configurations;
The content of these articles is based on our experience in developing an MSVS extension package plug-
in for PVS-Studio static analyzer. A more detailed in-depth references for the topics covered here are
available at the end of each article through the links to MSDN library and several other external
resources.
The articles will cover the extension development only for Visual Studio 2005 and later versions. This
limitation reflects that PVS-Studio also supports integration to Visual Studio starting only from version 8
(Visual Studio 2005). The main reason behind this is that a new extensibility API model was introduced
for Visual Studio 2005, and this new version is not backward-compatible with previous IDE APIs.
Creating and debugging Visual Studio VSPackage extension modules
There exists a number of ways to extend Microsoft Visual Studio features. On the most basic level it's
possible to automate simple routine user actions using macros. An add-In plug-in module can be used
for obtaining an access to environment's UI objects, such as menu commands, windows etc. Extension
of IDE's internal editors is possible through MEF (Managed Extensibility Framework) components
(starting with MSVS 2010). Finally, a plug-in of the Extension Package type (known as VSPackage) is best
suited for integrating large independent components into Visual Studio. VSPackage allows combining
the environment automation through Automation Object Model with usage of Managed Package
Framework classes (such as Package). It also provides the means of extending the automation model
itself by registering user-defined custom automation objects within it. Such user automation objects, in
turn, will become available through the same automation model from other user-created extensibility
packages, providing these packages with access to your custom components.
In its' earlier versions, PVS-Studio plug-in (versions 1.xx and 2.xx to be precise, when it was still known as
Viva64) existed as an Add-In package. Starting with PVS-Studio 3.0 it was redesigned as VSPackage
because the functionality Add-in was able to provide became insufficient for the tasks at hand and also
the debugging process was quite inconvenient. After all, we wanted to have our own logo on Visual
Studio splash screen!
Projects for VSPackage plug-in modules. Creating the extension package.
Contrary to Add-In plug-ins, developing VS extension packages requires the installation of Microsoft
Visual Studio SDK for a targeted version of IDE, i.e. a separate SDK should be installed with every version
of Visual Studio for which an extension is being developed. We will be examining the 2005, 2008, 2009
and 2012 versions of Visual Studio. Installation of Visual Studio SDK adds a standard project template for
Visual Studio Package (on the 'Other Project Types -> Extensibility' page) to VS template manager. If
selected, this template will generate a basic MSBuild project for an extension package, allowing several
parameters to be specified beforehand, such as a programming language to be used and the automatic
generation of several stub components for generic UI elements, such as menu item, an editor, user
toolwindow etc.
We will be using a C# VSPackage project (csproj), which is a project for managed dynamic-link library
(dll). The corresponding csproj MSBuild project for this managed assembly will also contain several XML
nodes specific to a Visual Studio package, such as VSCT compiler and IncludeinVSIX (in later IDE
versions).
The main class of an extension package should be inherited from the
Microsoft.VisualStudio.Shell.Package. This base class provides managed wrappers for IDE interaction
APIs, implementation of which is required from a fully-functional Visual Studio extension package.
public sealed class MyPackage: Package
{
public MyPackage ()
{}
...
}
The Package class allows overriding of its base Initialize method. This method receives execution control
at the moment of package initialization in the current session of IDE.
protected override void Initialize()
{
base.Initialize();
...
}
The initialization of the module will occur when it is invoked for the first time, but it also could be
triggered automatically, for example after IDE is started or when user enters a predefined environment
UI context state.
Being aware of the package's initialization and shutdown timings is crucial. It's quite possible that the
developer would be requesting some of Visual Studio functionality at the moment when it is still
unavailable to the package. During PVS-Studio development we've encountered several such situations
when the environment "punished us" for not understanding this, for instance, we are not allowed to
"straightforwardly" display message boxes after Visual Studio enters a shutdown process.
Debugging extension packages. Experimental Instance.
The task of debugging a plug-in module or extension intended for an integrated development
environment is not quite a typical one. Quite often such environment itself is utilized for plug-in's
development and debugging. Hooking up an unstable module to this IDE can lead to instability of the
environment itself. The necessity to uninstall a module under development from the IDE before every
debugging session, which in turn often requires restarting it, is also a major inconvenience (IDE could
block the dll that needs to be replaced by a newer version for debugging).
It should be noted that a VSPackage debugging process in this aspect is substantially easier than that of
an Add-In package. This was one of the main reasons for changing the project type of PVS-Studio plug-
in.
VSPackage solves the aforementioned development and debugging issues by utilizing Visual Studio
Experimental Instance mechanism. Such an experimental instance could be easily started by passing a
special command line argument:
"C:Program Files (x86)Microsoft Visual Studio 10.0
Common7IDEdevenv.exe" /RootSuffix Exp
An experimental instance of the environment utilizes a separate independent Windows registry hive
(called experimental hive) for storing all of its settings and component registration data. As such, any
modifications in the IDE's settings or changes in its component registration data, which were made
inside the experimental hive, will not affect the instance which is employed for the development of the
module (that is your main regular instance which is used by default).
Visual Studio SDK provides a special tool for creating or resetting such experimental instances —
CreateExpInstance. To create a new experimental hive, it should be executed with these arguments:
CreateExpInstance.exe /Reset /VSInstance=10.0 /RootSuffix=PVSExp
Executing this command will create a new experimental registry hive with a PVSExp suffix in its name for
the 10th version of IDE (Visual Studio 2010), also resetting all of its settings to their default values in
advance. The registry path for this new instance will look as follows:
HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio10.0PVSExp
While the Exp suffix is utilized by default for package debugging inside VSPackage template project,
other experimental hives with unique names could also be created by the developer at will. To start an
instance of the environment for the hive we've created earlier (containing PVSExp in its name), these
arguments should be used:
"C:Program Files (x86)Microsoft Visual Studio 10.0
Common7IDEdevenv.exe" /RootSuffix PVSExp
A capacity for creating several different experimental hives on a single local workstation could be quite
useful, as, for example, to provide a simultaneous and isolated development of several extension
packages.
After installing the SDK package, a link is created in the Visual Studio program's menu group for
resetting the default Experimental Instance for this version of the IDE (for instance, "Reset the Microsoft
Visual Studio 2010 Experimental Instance").
In the end, the faster you'll figure out how the debugging environment works, the fewer issues you'll
encounter in understanding how plug-in initialization works during development.
Registering and deploying Visual Studio extension packages
Registering a VS extension package requires registering a package itself, as well as registering all of the
components it integrates into the IDE (for example, menu items, option pages, user windows etc.). The
registration is accomplished by creating records corresponding to these components inside the main
system registry hive of Visual Studio.
All the information required for registration is placed, after building your VSPackage, inside a special
pkgdef file, according to several special attributes of the main class of your package (which itself should
be a subclass of the MPF 'Package' class). The pkgdef can also be created manually using the
CreatePkgDef utility. This tool collects all of the required module registration information from these
special attributes by the means of .NET reflection. Let's study these registration attributes in detail.
The PackageRegistration attribute tells the registration tool that this class is indeed a Visual Studio
extension package. Only if this attribute is discovered will the tool perform its search for additional ones.
[PackageRegistration(UseManagedResourcesOnly = true)]
The Guid attribute specifies a unique package module identifier, which will be used for creating a
registry sub-key for this module in Visual Studio hive.
[Guid("a0fcf0f3-577e-4c47-9847-5f152c16c02c")]
The InstalledProductRegistration attribute adds information to 'Visual Studio Help -> About' dialog and
the loading splash screen.
[InstalledProductRegistration("#110", "#112", "1.0",
IconResourceID = 400)]
The ProvideAutoLoad attribute links automatic module initialization with the activation of a specified
environment UI context. When a user enters this context, the package will be automatically loaded and
initialized. This is an example of setting module initialization to the opening of a solution file:
[ProvideAutoLoad("D2567162-F94F-4091-8798-A096E61B8B50")]
The GUID values for different IDE UI contexts can be found in the
Microsoft.VisualStudio.VSConstants.UICONTEXT class.
The ProvideMenuResource attribute specifies an ID of resource that contains user created menus and
commands for their registration inside IDE.
[ProvideMenuResource("Menus.ctmenu", 1)]
The DefaultRegistryRoot attribute specifies a path to be used for writing registration data to the system
registry. Starting with Visual Studio 2010 this attribute can be dropped as the corresponding data will be
present in manifest file of a VSIX container. An example of registering a package for Visual Studio 2008:
[DefaultRegistryRoot("SoftwareMicrosoftVisualStudio9.0")]
Registration of user-created components, such as toolwidows, editors, option pages etc. also requires
the inclusion of their corresponding attributes for the user's Package subclass. We will examine these
attributes separately when we will be examining corresponding components individually.
It's also possible to write any user-defined registry keys (and values to already existing keys) during
package registration through custom user registration attributes. Such attributes can be created by
inheriting the RegistrationAttribute abstract class.
[AttributeUsage(AttributeTargets.Class, Inherited = true,
AllowMultiple = false)]
public class CustomRegistrationAttribute : RegistrationAttribute
{
}
The RegistrationAttribute-derived attribute must override its Register and Unregister methods, which
are used to modify registration information in the system registry.
The RegPkg tool can be used for writing registration data to Windows registry. It will add all of the keys
from pkgdef file passed to it into the registry hive specified by the /root argument. For instance, the
RegPkg is utilized by default in Visual Studio VSPackage project template for registering the module in
the Visual Studio experimental hive, providing convenient seamless debugging of the package being
developed. After all of the registration information have been added to the registry, Visual Studio
(devenv.exe) should be started with '/setup' switch to complete registration for new components inside
the IDE.
Deploying plug-ins for developers and end-users. Package Load Key.
Before proceeding to describe the deployment process itself, one particular rule should be stressed:
Each time after a new version of the distribution containing your plug-in is created, this new
distribution should be tested on a system without Visual Studio SDK installed, as to make sure that it
will be registered correctly on the end-user system.
Today, as the releases of early versions of PVS-Studio are past us, we do not experience these kinds of
issues, but several of these early first versions were prone to them.
Deploying a package for Visual Studio 2005/2008 will require launching of regpkg tool for a pkgdef file
and passing the path to Visual Studio main registry hive into it. Alternately, all keys from a pkgdef can be
written to Windows registry manually. Here is the example of automatically writing all the registration
data from a pkgdef file by regpkg tool (in a single line):
RegPkg.exe /root:SoftwareMicrosoftVisualStudio9.0Exp
"/pkgdeffile:objDebugPVS-Studio-vs2008.pkgdef"
"C:MyPackageMyPackage.dll"
After adding the registration information to the system registry, it is necessary to start Visual Studio
with a /setup switch to complete the component registration. It is usually the last step in the installation
procedure of a new plug-in.
Devenv.exe /setup
Starting the environment with this switch instructs Visual Studio to absorb resource metadata for user-
created components from all available extension packages, so that these components will be correctly
displayed by IDE's interface. Starting devenv with this key will not open its' main GUI window.
We do not employ RepPkg utility as part of PVS-Studio deployment, instead manually writing required
data to the registry by using our stand-alone installer. We chose this method because we have no desire
of being dependent on some external third-party tools and we want full control over the installation
process. Still, we do use RegPkg during plug-in development for convenient debugging.
VSIX packages
Beginning from Visual Studio 2010, VSPackage deployment process can be significantly simplified
through the usage of VSIX packages. VSIX package itself is a common (Open Packaging Conventions)
archive containing plug-in's binary files and all of the other auxiliary files which are necessary for plug-
in's deployment. By passing such archive to the standard VSIXInstaller.exe utility, its contents will be
automatically registered in the IDE:
VSIXInstaller.exe MyPackage.vsix
VSIX installer could also be used with /uninstall switch to remove the previously installed package from
a system. A unique GUID of the extension package should be used to identify such package:
VSIXInstaller.exe /uninstall: 009084B1-6271-4621-A893-6D72F2B67A4D
Contents of a VSIX container are defined through the special vsixmanifest file, which should be added to
plug-in's project. Vsixmanifest file permits the following properties to be defined for an extension:
• targeted Visual Studio versions and editions, which will be supported by the plug-in;
• a unique GUID identifier;
• a list of components to be registered (VSPackage, MEF components, toolbox control etc.);
• general information about the plug-in to be installed (description, license, version, etc.);
To include additional files into a VSIX container, the IncludeInVSIX node should be added to their
declarations inside your MSBuild project (alternately, they could also be marked as included into VSIX
from their respective property windows, by opening it from Visual Studio Solution Explorer).
<Content Include="MyPackage.pdb">
<IncludeInVSIX>true</IncludeInVSIX>
</Content>
In fact, the VSIX file could be viewed as an almost full-fledged installer for extension packages on the
latest versions of Visual Studio (2010 and 2012), allowing the extensions to be deployed by a "one-click"
method. Publishing your VSIX container in the official Visual Studio Gallery for extensions allows end-
users to install such package through the Tools -> Extension Manager IDE dialog.
This new VSIX installation procedure in Visual Studio 2010 does substantially alleviate package
deployment for end-users (as well as for developers themselves). Some developers even had decided to
support only VS2010 IDE and versions above it, if only not to get involved with the development of a
package and installer for earlier IDE versions.
Unfortunately, several issues can be encountered when using VSIX installer together with Visual Studio
2010 extension manager interface. For instance, sometimes the extension's binary files are not removed
correctly after uninstall, which in turn blocks the VSIX installer from installing/reinstalling the same
extension. As such, we advise you not to depend upon the VSIX installer entirely and to provide some
backup, for example by directly removing your files from a previous plug-in installation before
proceeding with a new one.
Package Load Key
Each VSPackage module loaded into Visual Studio must possess a unique Package Load Key (PLK). PLK
key is specified through the ProvideLoadKey attribute for the Package subclass in 2005/2008 versions of
the IDE.
[ProvideLoadKey("Standard", "9.99", "MyPackage", "My Company", 100)]
Starting with Visual Studio 2010, the presence of a PLK, as well as of the ProvideLoadKey attribute
respectively, in a package is not required, but it can still be specified in case the module under
development is targeting several versions of MSVS. The PLK can be obtained by registering at the Visual
Studio Industry Partner portal, meaning it guarantees that the development environment can load only
packages certified by Microsoft.
However, systems containing Visual Studio SDK installed are exceptions to this, as Developer License Key
is installed together with the SDK. It allows the corresponding IDE to load any extension package,
regardless of validity of its PLK.
Considering the aforementioned, one more time it is necessary to stress the importance of testing the
distribution on a system without Visual Studio SDK present, because the extension package will operate
properly on developer's workstation regardless of its PLK correctness.
Extension registration specifics in the context of supporting several different versions of
Visual Studio IDE
By default, VSPackage project template will generate an extensibility project for the version of Visual
Studio that is used for the development. This is not a mandatory requirement though, so it is possible to
develop an extension for a particular version of IDE using a different one. It also should be noted that
after automatically upgrading a project file to a newer version through devenv /Upgrade switch, the
targeted version of the IDE and its' corresponding managed API libraries will remain unchanged, i.e.
from a previous version of Visual Studio.
To change the target of the extension to another version of Visual Studio (or to register an extension
into this version to be more precise), you should alter values passed to the DefaultRegistryRoot attribute
(only for 2005/2008 IDE versions, as starting from Visual Studio 2010 this attribute is no longer required)
or change the target version in the VSIX manifest file (for versions above 2008).
VSIX support appears only starting from Visual Studio 2010, so building and debugging the plug-in
targeted for the earlier IDE version from within Visual Studio 2010 (and later) requires setting up all the
aforementioned registration steps manually, without VSIX manifest. While changing target IDE version
one should also not forget to switch referenced managed assemblies, which contain COM interface
wrappers utilized by the plug-in, to the corresponding versions as well.
Altering the IDE target version of the plug-in affects the following Package subclass attributes:
• the InstalledProductRegistration attribute does not support overloading of its constructor with a
(Boolean, String, String, String) signature, starting from Visual Studio 2010;
• the presence of DefaultRegistryRoot and ProvideLoadKey attributes is not mandatory starting
from Visual Studio 2010, as similar values are now specified inside VSIX manifest;
References
1. MSDN. Experimental Build.
2. MSDN. How to: Register a VSPackage.
3. MSDN. VSIX Deployment.
4. MSDN. How to: Obtain a PLK for a VSPackage.
5. MZ-Tools. Resources about Visual Studio .NET extensibility.
6. MSDN. Creating Add-ins and Wizards.
7. MSDN. Using a Custom Registration Attribute to Register an Extension.
Other articles in this series
1. Introduction.
2. Creating, debugging and deploying extension packages for Microsoft Visual Studio
2005/2008/2010/2012.
3. Visual Studio Automation Object Model. EnvDTE interfaces.
4. Visual Studio commands.
5. Visual Studio tool windows.
6. Integrating into Visual Studio settings.
7. Visual C++ project model.

More Related Content

PDF
Visual Studio Automation Object Model. EnvDTE interfaces
PDF
Visual Studio2010 Product Overview
PDF
Compile open cpn on windows
PDF
Module 4: Introduction to ASP.NET 3.5 (Material)
PDF
JavaFX: A Rich Internet Application (RIA) Development Platform
PDF
Module 1: Introduction to .NET Framework 3.5 (Material)
PPTX
Installing JDK and first java program
PPT
Getting started with android dev and test perspective
Visual Studio Automation Object Model. EnvDTE interfaces
Visual Studio2010 Product Overview
Compile open cpn on windows
Module 4: Introduction to ASP.NET 3.5 (Material)
JavaFX: A Rich Internet Application (RIA) Development Platform
Module 1: Introduction to .NET Framework 3.5 (Material)
Installing JDK and first java program
Getting started with android dev and test perspective

What's hot (20)

PDF
Java ide comparision
PDF
ASP.NET vs ASP.NET Core
PPTX
Android Basic
PPTX
Android
PDF
Next Step, Android Studio!
PDF
Eclipse & java based modeling platforms for smart phone
KEY
An Introduction to Maven and Flex
PPTX
How to create android applications
PDF
Android dev o_auth
PDF
JEE Programming - 08 Enterprise Application Deployment
PDF
Softwaretestingtoolsfreeandopensourcefinal 150411221750-conversion-gate01
PDF
.Net Migration
PDF
Os Tibbittstutorial
PDF
Code One 2018 maven
PDF
Five Steps to Add AppUp .NET SDK to Microsoft Visual Studio
PPTX
How to configure Appium with android IDE & eclipse
PPTX
How to install Java and how to set the path
PDF
Creating InstallAnywhere Installations for Hybrid (32-Bit & 64-Bit) Windows A...
PDF
Windows azure sql_database_tutorials
PDF
Windows azure sql_database_tutorials
Java ide comparision
ASP.NET vs ASP.NET Core
Android Basic
Android
Next Step, Android Studio!
Eclipse & java based modeling platforms for smart phone
An Introduction to Maven and Flex
How to create android applications
Android dev o_auth
JEE Programming - 08 Enterprise Application Deployment
Softwaretestingtoolsfreeandopensourcefinal 150411221750-conversion-gate01
.Net Migration
Os Tibbittstutorial
Code One 2018 maven
Five Steps to Add AppUp .NET SDK to Microsoft Visual Studio
How to configure Appium with android IDE & eclipse
How to install Java and how to set the path
Creating InstallAnywhere Installations for Hybrid (32-Bit & 64-Bit) Windows A...
Windows azure sql_database_tutorials
Windows azure sql_database_tutorials
Ad

Similar to Creating, debugging and deploying extension packages for Microsoft Visual Studio 2005/2008/2010/2012 (20)

PDF
Visual Studio Ceases Support of Add-Ins in Community Previews 14
PDF
Visual Studio commands
PDF
Visual Studio 2008 Overview
DOCX
Tutorial test driven development with Visual Studio 2012
PPT
Vsto 3 Excel Add-in SNUG
PPT
Vsto 3 Snug
PPTX
Visual Studio Software architecture
PPTX
Workshop: Modularization of .NET Applications
PPT
Working in Visual Studio.Net
PDF
tutorials-visual-studio_visual-studio-2015-preview-comes-with-emulator-for-an...
PPT
Vs2005p
PDF
Verifying projects utilizing Marmalade SDK with PVS-Studio analyzer.
PDF
Visual Basic In Easy Steps Covers Visual Basic 2015 Fourth Mcgrath
PDF
Unit -II Introduction to visual programming.pdf
DOCX
Tutorial 1
PDF
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PPTX
Extend Eclipse p2 framework capabilities: Add your custom installation steps
PPTX
Coded ui - lesson 1 - overview
PDF
Trying to Sell PVS-Studio to Google, or New Bugs in Chromium
PDF
XCode Templates tutorial – How To Create Custom Template Step By Step.pdf
Visual Studio Ceases Support of Add-Ins in Community Previews 14
Visual Studio commands
Visual Studio 2008 Overview
Tutorial test driven development with Visual Studio 2012
Vsto 3 Excel Add-in SNUG
Vsto 3 Snug
Visual Studio Software architecture
Workshop: Modularization of .NET Applications
Working in Visual Studio.Net
tutorials-visual-studio_visual-studio-2015-preview-comes-with-emulator-for-an...
Vs2005p
Verifying projects utilizing Marmalade SDK with PVS-Studio analyzer.
Visual Basic In Easy Steps Covers Visual Basic 2015 Fourth Mcgrath
Unit -II Introduction to visual programming.pdf
Tutorial 1
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
Extend Eclipse p2 framework capabilities: Add your custom installation steps
Coded ui - lesson 1 - overview
Trying to Sell PVS-Studio to Google, or New Bugs in Chromium
XCode Templates tutorial – How To Create Custom Template Step By Step.pdf
Ad

Recently uploaded (20)

PDF
NewMind AI Weekly Chronicles - August'25-Week II
PPTX
1. Introduction to Computer Programming.pptx
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
A novel scalable deep ensemble learning framework for big data classification...
PDF
Getting Started with Data Integration: FME Form 101
PDF
A comparative study of natural language inference in Swahili using monolingua...
PDF
Hybrid model detection and classification of lung cancer
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
August Patch Tuesday
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
DP Operators-handbook-extract for the Mautical Institute
PPTX
TLE Review Electricity (Electricity).pptx
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Zenith AI: Advanced Artificial Intelligence
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
NewMind AI Weekly Chronicles - August'25-Week II
1. Introduction to Computer Programming.pptx
Encapsulation_ Review paper, used for researhc scholars
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
A novel scalable deep ensemble learning framework for big data classification...
Getting Started with Data Integration: FME Form 101
A comparative study of natural language inference in Swahili using monolingua...
Hybrid model detection and classification of lung cancer
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
August Patch Tuesday
Building Integrated photovoltaic BIPV_UPV.pdf
DP Operators-handbook-extract for the Mautical Institute
TLE Review Electricity (Electricity).pptx
Programs and apps: productivity, graphics, security and other tools
Zenith AI: Advanced Artificial Intelligence
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Digital-Transformation-Roadmap-for-Companies.pptx
cloud_computing_Infrastucture_as_cloud_p
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf

Creating, debugging and deploying extension packages for Microsoft Visual Studio 2005/2008/2010/2012

  • 1. Creating, debugging and deploying extension packages for Microsoft Visual Studio 2005/2008/2010/2012 Author: Paul Eremeev Date: 12.10.2012 Abstract This article contains the overview of several different methods for extending Visual Studio IDE. The creation, debugging, registration and end-user deployment of Visual Studio extension packages will be explained in detail. Introduction The following series of articles is dedicated to the development of the extension package for Visual Studio 2005/2008/2010/2012 IDEs utilizing .NET framework and C# programming language. The following topics will be covered: • basic information on creating and debugging of MSVS plug-ins and maintaining these extensibility projects for several versions of Visual Studio inside a common source code base; • overview of Automation Object Model and various Managed Package Framework (MPF) classes • extending interface of the IDE though the automation object model's API (EnvDTE) and MPF (Managed Package Framework) classes with custom menus, toolbars, windows and options pages; • utilizing Visual C++ project automation model for gathering data needed to operate an external preprocessor/compiler, such as compilation arguments and settings for different platforms and configurations; The content of these articles is based on our experience in developing an MSVS extension package plug- in for PVS-Studio static analyzer. A more detailed in-depth references for the topics covered here are available at the end of each article through the links to MSDN library and several other external resources. The articles will cover the extension development only for Visual Studio 2005 and later versions. This limitation reflects that PVS-Studio also supports integration to Visual Studio starting only from version 8 (Visual Studio 2005). The main reason behind this is that a new extensibility API model was introduced for Visual Studio 2005, and this new version is not backward-compatible with previous IDE APIs. Creating and debugging Visual Studio VSPackage extension modules There exists a number of ways to extend Microsoft Visual Studio features. On the most basic level it's possible to automate simple routine user actions using macros. An add-In plug-in module can be used for obtaining an access to environment's UI objects, such as menu commands, windows etc. Extension of IDE's internal editors is possible through MEF (Managed Extensibility Framework) components
  • 2. (starting with MSVS 2010). Finally, a plug-in of the Extension Package type (known as VSPackage) is best suited for integrating large independent components into Visual Studio. VSPackage allows combining the environment automation through Automation Object Model with usage of Managed Package Framework classes (such as Package). It also provides the means of extending the automation model itself by registering user-defined custom automation objects within it. Such user automation objects, in turn, will become available through the same automation model from other user-created extensibility packages, providing these packages with access to your custom components. In its' earlier versions, PVS-Studio plug-in (versions 1.xx and 2.xx to be precise, when it was still known as Viva64) existed as an Add-In package. Starting with PVS-Studio 3.0 it was redesigned as VSPackage because the functionality Add-in was able to provide became insufficient for the tasks at hand and also the debugging process was quite inconvenient. After all, we wanted to have our own logo on Visual Studio splash screen! Projects for VSPackage plug-in modules. Creating the extension package. Contrary to Add-In plug-ins, developing VS extension packages requires the installation of Microsoft Visual Studio SDK for a targeted version of IDE, i.e. a separate SDK should be installed with every version of Visual Studio for which an extension is being developed. We will be examining the 2005, 2008, 2009 and 2012 versions of Visual Studio. Installation of Visual Studio SDK adds a standard project template for Visual Studio Package (on the 'Other Project Types -> Extensibility' page) to VS template manager. If selected, this template will generate a basic MSBuild project for an extension package, allowing several parameters to be specified beforehand, such as a programming language to be used and the automatic generation of several stub components for generic UI elements, such as menu item, an editor, user toolwindow etc. We will be using a C# VSPackage project (csproj), which is a project for managed dynamic-link library (dll). The corresponding csproj MSBuild project for this managed assembly will also contain several XML nodes specific to a Visual Studio package, such as VSCT compiler and IncludeinVSIX (in later IDE versions). The main class of an extension package should be inherited from the Microsoft.VisualStudio.Shell.Package. This base class provides managed wrappers for IDE interaction APIs, implementation of which is required from a fully-functional Visual Studio extension package. public sealed class MyPackage: Package { public MyPackage () {} ... } The Package class allows overriding of its base Initialize method. This method receives execution control at the moment of package initialization in the current session of IDE. protected override void Initialize() { base.Initialize(); ...
  • 3. } The initialization of the module will occur when it is invoked for the first time, but it also could be triggered automatically, for example after IDE is started or when user enters a predefined environment UI context state. Being aware of the package's initialization and shutdown timings is crucial. It's quite possible that the developer would be requesting some of Visual Studio functionality at the moment when it is still unavailable to the package. During PVS-Studio development we've encountered several such situations when the environment "punished us" for not understanding this, for instance, we are not allowed to "straightforwardly" display message boxes after Visual Studio enters a shutdown process. Debugging extension packages. Experimental Instance. The task of debugging a plug-in module or extension intended for an integrated development environment is not quite a typical one. Quite often such environment itself is utilized for plug-in's development and debugging. Hooking up an unstable module to this IDE can lead to instability of the environment itself. The necessity to uninstall a module under development from the IDE before every debugging session, which in turn often requires restarting it, is also a major inconvenience (IDE could block the dll that needs to be replaced by a newer version for debugging). It should be noted that a VSPackage debugging process in this aspect is substantially easier than that of an Add-In package. This was one of the main reasons for changing the project type of PVS-Studio plug- in. VSPackage solves the aforementioned development and debugging issues by utilizing Visual Studio Experimental Instance mechanism. Such an experimental instance could be easily started by passing a special command line argument: "C:Program Files (x86)Microsoft Visual Studio 10.0 Common7IDEdevenv.exe" /RootSuffix Exp An experimental instance of the environment utilizes a separate independent Windows registry hive (called experimental hive) for storing all of its settings and component registration data. As such, any modifications in the IDE's settings or changes in its component registration data, which were made inside the experimental hive, will not affect the instance which is employed for the development of the module (that is your main regular instance which is used by default). Visual Studio SDK provides a special tool for creating or resetting such experimental instances — CreateExpInstance. To create a new experimental hive, it should be executed with these arguments: CreateExpInstance.exe /Reset /VSInstance=10.0 /RootSuffix=PVSExp Executing this command will create a new experimental registry hive with a PVSExp suffix in its name for the 10th version of IDE (Visual Studio 2010), also resetting all of its settings to their default values in advance. The registry path for this new instance will look as follows: HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio10.0PVSExp While the Exp suffix is utilized by default for package debugging inside VSPackage template project, other experimental hives with unique names could also be created by the developer at will. To start an
  • 4. instance of the environment for the hive we've created earlier (containing PVSExp in its name), these arguments should be used: "C:Program Files (x86)Microsoft Visual Studio 10.0 Common7IDEdevenv.exe" /RootSuffix PVSExp A capacity for creating several different experimental hives on a single local workstation could be quite useful, as, for example, to provide a simultaneous and isolated development of several extension packages. After installing the SDK package, a link is created in the Visual Studio program's menu group for resetting the default Experimental Instance for this version of the IDE (for instance, "Reset the Microsoft Visual Studio 2010 Experimental Instance"). In the end, the faster you'll figure out how the debugging environment works, the fewer issues you'll encounter in understanding how plug-in initialization works during development. Registering and deploying Visual Studio extension packages Registering a VS extension package requires registering a package itself, as well as registering all of the components it integrates into the IDE (for example, menu items, option pages, user windows etc.). The registration is accomplished by creating records corresponding to these components inside the main system registry hive of Visual Studio. All the information required for registration is placed, after building your VSPackage, inside a special pkgdef file, according to several special attributes of the main class of your package (which itself should be a subclass of the MPF 'Package' class). The pkgdef can also be created manually using the CreatePkgDef utility. This tool collects all of the required module registration information from these special attributes by the means of .NET reflection. Let's study these registration attributes in detail. The PackageRegistration attribute tells the registration tool that this class is indeed a Visual Studio extension package. Only if this attribute is discovered will the tool perform its search for additional ones. [PackageRegistration(UseManagedResourcesOnly = true)] The Guid attribute specifies a unique package module identifier, which will be used for creating a registry sub-key for this module in Visual Studio hive. [Guid("a0fcf0f3-577e-4c47-9847-5f152c16c02c")] The InstalledProductRegistration attribute adds information to 'Visual Studio Help -> About' dialog and the loading splash screen. [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] The ProvideAutoLoad attribute links automatic module initialization with the activation of a specified environment UI context. When a user enters this context, the package will be automatically loaded and initialized. This is an example of setting module initialization to the opening of a solution file: [ProvideAutoLoad("D2567162-F94F-4091-8798-A096E61B8B50")]
  • 5. The GUID values for different IDE UI contexts can be found in the Microsoft.VisualStudio.VSConstants.UICONTEXT class. The ProvideMenuResource attribute specifies an ID of resource that contains user created menus and commands for their registration inside IDE. [ProvideMenuResource("Menus.ctmenu", 1)] The DefaultRegistryRoot attribute specifies a path to be used for writing registration data to the system registry. Starting with Visual Studio 2010 this attribute can be dropped as the corresponding data will be present in manifest file of a VSIX container. An example of registering a package for Visual Studio 2008: [DefaultRegistryRoot("SoftwareMicrosoftVisualStudio9.0")] Registration of user-created components, such as toolwidows, editors, option pages etc. also requires the inclusion of their corresponding attributes for the user's Package subclass. We will examine these attributes separately when we will be examining corresponding components individually. It's also possible to write any user-defined registry keys (and values to already existing keys) during package registration through custom user registration attributes. Such attributes can be created by inheriting the RegistrationAttribute abstract class. [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] public class CustomRegistrationAttribute : RegistrationAttribute { } The RegistrationAttribute-derived attribute must override its Register and Unregister methods, which are used to modify registration information in the system registry. The RegPkg tool can be used for writing registration data to Windows registry. It will add all of the keys from pkgdef file passed to it into the registry hive specified by the /root argument. For instance, the RegPkg is utilized by default in Visual Studio VSPackage project template for registering the module in the Visual Studio experimental hive, providing convenient seamless debugging of the package being developed. After all of the registration information have been added to the registry, Visual Studio (devenv.exe) should be started with '/setup' switch to complete registration for new components inside the IDE. Deploying plug-ins for developers and end-users. Package Load Key. Before proceeding to describe the deployment process itself, one particular rule should be stressed: Each time after a new version of the distribution containing your plug-in is created, this new distribution should be tested on a system without Visual Studio SDK installed, as to make sure that it will be registered correctly on the end-user system. Today, as the releases of early versions of PVS-Studio are past us, we do not experience these kinds of issues, but several of these early first versions were prone to them. Deploying a package for Visual Studio 2005/2008 will require launching of regpkg tool for a pkgdef file and passing the path to Visual Studio main registry hive into it. Alternately, all keys from a pkgdef can be written to Windows registry manually. Here is the example of automatically writing all the registration data from a pkgdef file by regpkg tool (in a single line):
  • 6. RegPkg.exe /root:SoftwareMicrosoftVisualStudio9.0Exp "/pkgdeffile:objDebugPVS-Studio-vs2008.pkgdef" "C:MyPackageMyPackage.dll" After adding the registration information to the system registry, it is necessary to start Visual Studio with a /setup switch to complete the component registration. It is usually the last step in the installation procedure of a new plug-in. Devenv.exe /setup Starting the environment with this switch instructs Visual Studio to absorb resource metadata for user- created components from all available extension packages, so that these components will be correctly displayed by IDE's interface. Starting devenv with this key will not open its' main GUI window. We do not employ RepPkg utility as part of PVS-Studio deployment, instead manually writing required data to the registry by using our stand-alone installer. We chose this method because we have no desire of being dependent on some external third-party tools and we want full control over the installation process. Still, we do use RegPkg during plug-in development for convenient debugging. VSIX packages Beginning from Visual Studio 2010, VSPackage deployment process can be significantly simplified through the usage of VSIX packages. VSIX package itself is a common (Open Packaging Conventions) archive containing plug-in's binary files and all of the other auxiliary files which are necessary for plug- in's deployment. By passing such archive to the standard VSIXInstaller.exe utility, its contents will be automatically registered in the IDE: VSIXInstaller.exe MyPackage.vsix VSIX installer could also be used with /uninstall switch to remove the previously installed package from a system. A unique GUID of the extension package should be used to identify such package: VSIXInstaller.exe /uninstall: 009084B1-6271-4621-A893-6D72F2B67A4D Contents of a VSIX container are defined through the special vsixmanifest file, which should be added to plug-in's project. Vsixmanifest file permits the following properties to be defined for an extension: • targeted Visual Studio versions and editions, which will be supported by the plug-in; • a unique GUID identifier; • a list of components to be registered (VSPackage, MEF components, toolbox control etc.); • general information about the plug-in to be installed (description, license, version, etc.); To include additional files into a VSIX container, the IncludeInVSIX node should be added to their declarations inside your MSBuild project (alternately, they could also be marked as included into VSIX from their respective property windows, by opening it from Visual Studio Solution Explorer). <Content Include="MyPackage.pdb"> <IncludeInVSIX>true</IncludeInVSIX> </Content> In fact, the VSIX file could be viewed as an almost full-fledged installer for extension packages on the latest versions of Visual Studio (2010 and 2012), allowing the extensions to be deployed by a "one-click"
  • 7. method. Publishing your VSIX container in the official Visual Studio Gallery for extensions allows end- users to install such package through the Tools -> Extension Manager IDE dialog. This new VSIX installation procedure in Visual Studio 2010 does substantially alleviate package deployment for end-users (as well as for developers themselves). Some developers even had decided to support only VS2010 IDE and versions above it, if only not to get involved with the development of a package and installer for earlier IDE versions. Unfortunately, several issues can be encountered when using VSIX installer together with Visual Studio 2010 extension manager interface. For instance, sometimes the extension's binary files are not removed correctly after uninstall, which in turn blocks the VSIX installer from installing/reinstalling the same extension. As such, we advise you not to depend upon the VSIX installer entirely and to provide some backup, for example by directly removing your files from a previous plug-in installation before proceeding with a new one. Package Load Key Each VSPackage module loaded into Visual Studio must possess a unique Package Load Key (PLK). PLK key is specified through the ProvideLoadKey attribute for the Package subclass in 2005/2008 versions of the IDE. [ProvideLoadKey("Standard", "9.99", "MyPackage", "My Company", 100)] Starting with Visual Studio 2010, the presence of a PLK, as well as of the ProvideLoadKey attribute respectively, in a package is not required, but it can still be specified in case the module under development is targeting several versions of MSVS. The PLK can be obtained by registering at the Visual Studio Industry Partner portal, meaning it guarantees that the development environment can load only packages certified by Microsoft. However, systems containing Visual Studio SDK installed are exceptions to this, as Developer License Key is installed together with the SDK. It allows the corresponding IDE to load any extension package, regardless of validity of its PLK. Considering the aforementioned, one more time it is necessary to stress the importance of testing the distribution on a system without Visual Studio SDK present, because the extension package will operate properly on developer's workstation regardless of its PLK correctness. Extension registration specifics in the context of supporting several different versions of Visual Studio IDE By default, VSPackage project template will generate an extensibility project for the version of Visual Studio that is used for the development. This is not a mandatory requirement though, so it is possible to develop an extension for a particular version of IDE using a different one. It also should be noted that after automatically upgrading a project file to a newer version through devenv /Upgrade switch, the targeted version of the IDE and its' corresponding managed API libraries will remain unchanged, i.e. from a previous version of Visual Studio. To change the target of the extension to another version of Visual Studio (or to register an extension into this version to be more precise), you should alter values passed to the DefaultRegistryRoot attribute (only for 2005/2008 IDE versions, as starting from Visual Studio 2010 this attribute is no longer required) or change the target version in the VSIX manifest file (for versions above 2008).
  • 8. VSIX support appears only starting from Visual Studio 2010, so building and debugging the plug-in targeted for the earlier IDE version from within Visual Studio 2010 (and later) requires setting up all the aforementioned registration steps manually, without VSIX manifest. While changing target IDE version one should also not forget to switch referenced managed assemblies, which contain COM interface wrappers utilized by the plug-in, to the corresponding versions as well. Altering the IDE target version of the plug-in affects the following Package subclass attributes: • the InstalledProductRegistration attribute does not support overloading of its constructor with a (Boolean, String, String, String) signature, starting from Visual Studio 2010; • the presence of DefaultRegistryRoot and ProvideLoadKey attributes is not mandatory starting from Visual Studio 2010, as similar values are now specified inside VSIX manifest; References 1. MSDN. Experimental Build. 2. MSDN. How to: Register a VSPackage. 3. MSDN. VSIX Deployment. 4. MSDN. How to: Obtain a PLK for a VSPackage. 5. MZ-Tools. Resources about Visual Studio .NET extensibility. 6. MSDN. Creating Add-ins and Wizards. 7. MSDN. Using a Custom Registration Attribute to Register an Extension. Other articles in this series 1. Introduction. 2. Creating, debugging and deploying extension packages for Microsoft Visual Studio 2005/2008/2010/2012. 3. Visual Studio Automation Object Model. EnvDTE interfaces. 4. Visual Studio commands. 5. Visual Studio tool windows. 6. Integrating into Visual Studio settings. 7. Visual C++ project model.