Bootstrapping of VS packages and VSIX extensions in VS2010
Short bio: Dmitry has been at Microsoft for about 10 years working on several areas of Visual Studio. For Visual Studio 2010, he helped to design and implement PkgDef management, VSIX technologies, and hosting of MEF components.
Visual Studio 2010 uses two technologies to make it much simpler to deploy VS extensions:
- VS Packages don’t need to write registration information directly to the registry. They can provide all their registration information in PkgDef files, instead.
- VSIX is the new deployment model available for deploying VS 2010 extensions. It is fully integrated into the IDE and provides a simple model for publishing extensions to the Visual Studio Gallery.
Given different (previously supported and new) types of extensions available in VS2010 it might be not clear how they are being discovered and bootstrapped by the IDE. This post is an attempt to shed some light onto this area of VS Platform.
The Visual Studio process is launched by executing devenv.exe, which is located in <VsInstallRootFolder>Common7IDE. After doing some critical steps like command line parsing and Watson integration initialization (the technology managing crash/hang dumps), devenv.exe initializes the PkgDef Management logic. [Note that Express VS SKUs are launched using different executables but internally they have a very similar logic to devenv.exe.]
PkgDef Management draws its initialization parameters from the file devenv.pkgdef, which is located next to devenv.exe (also called the “Master PkgDef”). This file defines the locations where VS should be looking for other PkgDef files and installed VSIX extensions.
Here is the content of a sample devenv.pkgdef file:
The table below describes some variables that will typically be in the Master PkgDef file:
The root registry location under HKEY_CURRENT_USER where user settings and configuration cache are stored.
The list of folders where to search for PkgDef files. The list can also include specific PkgDef files.
The root folder under which machine wide VSIXs are deployed.
The root folder under which user specific VSIXs are deployed.
The main job of PkgDef Management is to locate, load PkgDef files and merge them with the rest the configuration data that is located under HKLMSOFTWAREMicrosoftVisualStudio10.0 (or HKLMWow6432NodeSoftwareMicrosoftVisualStudio10.0 on 64-bit OSs). The folders listed in the PkgDefSearchPath are scanned recursively and PkgDef files found there are loaded. PkgDef Management then scans recursively starting from extension folders under UserExtensionsRootFolder and loads only those PkgDef files that belong to extensions marked as “Enabled” in the Extension Manager dialog.
Once all Visual Studio configuration data is loaded and merged, it is then cached under HKCUSoftwareMicrosoftVisualStudio10.0_Config registry root. Since this cache can be updated at any moment don’t ever edit it. If you need to modify the configuration data (for example to register your VS package) add a PkgDef file instead to your extension. [Don’t ever hardcode VS registry paths into your code. Use ShellSettingsManager class from Microsoft.VisualStudio.Shell.10.0.dll to work with VS settings and configuration data.]
Once the configuration data is ready, the rest of Visual Studio can use it to initialize its core services and build the UI (main frame, menus, command bars, tool windows, etc.) This step deserves its own discussion but it is beyond of the scope of this article. The very last step before the IDE starts receiving user input is to initialize the main message loop. SOleComponentManager service is responsible for managing VS message pump and it as well deserves its own blog post (or even few).
So, how does all this tie to the Extension Manager and VSIX extensions? At some point SVsExtensionManager service will be invoked (which depending on the scenario could be before or after VS became responsive). The service recursively scans below the ApplicationExtensionsFolder folder defined in the Master PkgDef file for extension.vsixmanifest files. All found VSIX extensions under ApplicationExtensionsFolder become available to VS.
UserExtensionsRootFolder in the Master PkgDef file specifies the path under which per-user VSIXs are installed (via the the Extension Manager dialog or by the Standalone VSIX installer). Extensions (VSIXs) installed into these “per user” folders are only loaded if the following criteria (as of the Beta 2 release) are met:
- They are loaded only if the user is not an administrator on the machine, or
- The highlighted below option is checked in Tools | Options.
Only the VSIXs that are marked as “Enabled” in the Extension Manager dialog are considered by the service and made available to VS.
After a VSIX is enabled or disabled, VS might need to be restarted for this change to take an effect. This is true for VSIXs containing PkgDef files because, as it is described above, any changes to PkgDef files are processed only during the startup of VS.
Finally a short list of troubleshooting options for VS startup issues:
- Run devenv.exe /log [<optional log file path>] for generating a detailed log of VS startup activities. If the log file path is not specified then by default the log is written into %APPDATA%MicrosoftVisualStudio10.0ActivityLog.xml. Open the log in a web browser and look for any “yellow” or “red” entries to quickly locate the problem spots.
- If VS fails to start or some feature becomes broken after installing a new VSIX, then run devenv.exe /SafeMode to re-launch VS with only the “safe” set of extensions enabled. Then go to the Extension Manager dialog and disable the extensions that have been recently installed.
- If it is not clear which VSIX caused the problem, run devenv.exe /ResetUserData in order to bring VS to the known initial state (as if it has been just installed).