At the company I work for we have developed a Visual Studio extension that adds a variety of different project templates that incorporate our standards for authentication, authorization, logging, configuration, etc. We have templates for ASP.NET MVC, ASP.NET MVC with Angular, .NET Console, and others. We make that extension available through our own custom extension gallery in Visual Studio. Creating a private extension gallery may sound complicated, but all it really entails is creating an XML file that represents the atom (RSS) feed. Below is an example of the XML file from the Microsoft documentation.
<?xml version="1.0" encoding="utf-8" ?> - <feed xmlns="http://www.w3.org/2005/Atom"> <title type="text" /> <id>uuid:bcecded5-97c8-4d24-96f1-7d9e16652433;id=1</id> <updated>2011-04-14T21:25:48Z</updated> - <entry> <id>SelectionHighlight..a14874d2-8199-4a60-af8a-11d6447813aa</id> <title type="text">Highlight all occurrences of selected word</title> <summary type="text">This extends the editor to highlight ....</summary> <published>2011-04-14T14:24:51-07:00</published> <updated>2011-04-14T14:24:22-07:00</updated> - <author> <name>Microsoft</name> </author> <link rel="icon" href="VSIXImages/SelectionHighlight..a14874d2-8199-4a60-af8a-11d6447813aa_Icon_SelectionHighlightIcon.jpg" /> <link rel="previewimage" href="VSIXImages/SelectionHighlight..a14874d2-8199-4a60-af8a-11d6447813aa_PreviewImage_SelectionHighlight.jpg" /> <content type="application/octet-stream" src="SelectionHighlight.vsix" /> - <Vsix xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/developer/vsx-syndication-schema/2010"> <Id>SelectionHighlight..a14874d2-8199-4a60-af8a-11d6447813aa</Id> <Version>1.31</Version> <References /> <Rating xsi:nil="true" /> <RatingCount xsi:nil="true" /> <DownloadCount xsi:nil="true" /> </Vsix> </entry> - <entry> <id>Template_Wizard_239.Microsoft.3b38a7e3-5cbc-4389-a92a-d82tyc2ed592</id> ... </entry> </feed>
Once you have created the XML file for your private extension gallery you need to configure Visual Studio. You can do this two different ways. You can add the extension gallery in Visual Studio by going to Tools –> Options in the menu. Then selecting Extensions and Updates under the Environment section as shown below. You then enter a Name and a URL path to the Atom XML file. What this process does is create new entries in the Visual Studio registry section.
Another way of adding the private extension gallery is to manually create the registry entries yourself. This is the option we use as part of our developer workstation setup script. This worked well until the release of Visual Studio 2017. Visual Studio 2017 moved to a registry free install to enable multiple installations of Visual Studio side by side, on the same machine. So if Visual Studio 2017 is no longer using the registry how are they storing their configuration? Well it turns out that Visual Studio 2017 is still using a registry it just happens to be a private registry. Visual Studio 2017’s registry is maintained in a privateregistry.bin file located in the Local App Data %localappdata%\Microsoft\VisualStudio\[config]\privateregistry.bin
where [config]
corresponds to the configuration hive you would like to browse. You can even load the registry file into regedit.exe and modify it.
To open the file in regedit:
- Close Visual Studio
- Start Regedit.exe
- Select the
HKEY_LOCAL_MACHINE
node - From the main menu, select
File
->Load Hive...
and select the private registry file. That file is stored in the Local App Data%localappdata%\Microsoft\VisualStudio\[config]\privateregistry.bin
where[config]
corresponds to the configuration hive you would like to browse - It will prompt for a name – that represents the name that will be displayed under (e.g.
IsolatedHive
) - Now you should be able to browse the registry under the hive you created
- Before launching Visual Studio, you need to unload it: From the main menu
File
->Unload Hive
before attempting to run VS (otherwise regedit keeps the file locked, and Visual Studio will fail to launch)
Now that we know how the configuration for Visual Studio 2017 works lets discuss how we can automate the adding of the registry entries for our private extension gallery. The Microsoft documentation suggest modifying the registry by using a .pkgdef file. A .pkgdef file is way to encapsulate application configuration information in an easily editable, distributable, and deployable form. It was introduced in Visual Studio 2008 SP1 to support the configuration of Isolated Shell applications. Although the documentation doesn’t say how to apply/install your pkgdef file once you create it, the recommended way is by installing it as part of a VSIX package.
To create a VSIX package you need to have the Visual Studio extension development workload installed.
The first step is to create the project by selecting File –> New –> Project and then selecting VSIX Project under Extensibility.
Next add a new .pkgdef file named CompanyPrivateGallery.pkgdef. Open the pkgdef file and add the following:
[$RootKey$\ExtensionManager\Repositories\{0423a97a-3691-4d8a-9c2c-1a9aabbb5273}] @="file://AcmeCompany/DeveloperInstall/Visual%20Studio%20Extensions/feed.xml" "Priority"=100 "Protocol"="Atom Feed" "DisplayName"="Acme Company"
- The
Priority
value determines the order in which the galleries are listed in the Options dialog box. Visual Studio Gallery has priority 10 and the Samples Gallery has priority 20. Private galleries start at priority 100. If several galleries have the same priority value, the order in which they appear is determined by the values of their localizedDisplayName
attributes. -
The
Protocol
value is required for Atom-based or SharePoint-based galleries.
You should be able run your project in debug now which will startup a new instance of Visual Studio with your extension installed. You should also see your private gallery listed in the Extensions and Updates menu. Unfortunately I could never get the private gallery to show up. I found several discussions were others were having the same issue, but never found a solution to my problem.
- Adding a Custom ExtentionManger atom feed to a private gallery via pkgdef fails
- How do I manage a private gallery in vs 2017 using registry like I did in vs 2015?
Since I couldn’t get the pkgdef file to update the Visual Studio registry I decided to write a script that:
- Loads the private registry file for each instance of Visual Studio installed
- Adds the necessary registry entries
- Unloads the private registry file
Here is the finished PowerShell script.
Get-ChildItem "$env:LOCALAPPDATA\Microsoft\VisualStudio\15.0_*" | Foreach-Object { & reg load "HKLM\_TMPVS_$($_.BaseName)" "$($_.FullName)\privateregistry.bin" (Get-Content CompanyPrivateGallery_Template.reg).replace('{{VS_VERSION}}', $_.BaseName) | Set-Content "CompanyPrivateGallery_$($_.BaseName)" ®edit /s "CompanyPrivateGallery_$($_.BaseName)" & reg unload "HKLM\_TMPVS_$($_.BaseName)" }
I want to point out the second line of the for loop. It is doing a string replacement on a registry template file so that when the registry file is merged it merges into the correct Visual Studio instance. Here is what the registry template file looks like.
[HKEY_LOCAL_MACHINE\_TMPVS_{{VS_VERSION}}\Software\Microsoft\VisualStudio\{{VS_VERSION}}\ExtensionManager\Repositories\{0423a97a-3691-4d8a-9c2c-1a9aabbb5273}] @="file://AcmeCompany/DeveloperInstall/Visual%20Studio%20Extensions/feed.xml" "Priority"=dword:00000064 "Protocol"="" "DisplayName"="Acme Company"
I hope this is helpful to someone. This process took quite a while to work through and I hope to save that time for as many people as I can.
Related Links
- Private Galleries
- How to: Manage a Private Gallery By Using Registry Settings
- How to: Create an Atom Feed for a Private Gallery
- CreatePkgDef Utility
- Building extensions for Visual Studio
- VSIX Project Template
- Extensibility Tools
- Hello World Extension Tutorial
- How to examine Visual Studio 2017 registry
- Changes in Visual Studio 2017 extensibility
- What’s A PkgDef? And Why?
- Changing Visual Studio 2017 private registry settings
- Adding a Custom ExtentionManger atom feed to a private gallery via pkgdef fails
- How do I manage a private gallery in vs 2017 using registry like I did in vs 2015?
- About the new privateregistry.bin file of Visual Studio 2017
3 responses to “How to Add a Private Extension Gallery in Visual Studio 2017”
[…] Add a private extension gallery to Visual Studio which I detailed in this article […]
LikeLike
Nice job. It’s of great help to me. When I execute the script, I’m find the script needs some modification.
1. the statement ‘®edit /s “CompanyPrivateGallery_$($_.BaseName)”‘ doesn’t work. I don’t known why. So I modified the script, replace “regedit” with “reg add”. It’s looks like :
$keyName=”HKLM\_TMPVS_$($_.BaseName)\Software\Microsoft\VisualStudio\$($_.BaseName)_Config\ExtensionManager\Repositories\{60926e9d-cfec-49b6-8706-43b6ce5a4df3}”
& reg add $keyName /ve /d http://servername/GalleryService.svc
& reg add $keyName /v Priority /t REG_DWORD /d 00000064
& reg add $keyName /v Protocol /d VSGallery
& reg add $keyName /v DisplayName /d “GalleryName”
2. In VS 2017, the key, ‘ExtensionManager\Repositories’, is under “{{VS_VERSION}}_Config”
3. In order to use script file and template file in same directory, I’m add some statement (ref: https://blogs.msdn.microsoft.com/powershell/2007/06/19/get-scriptdirectory-to-the-rescue/). It’s looks like:
function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}
$regFile = Join-Path (Get-ScriptDirectory) CompanyPrivateGallery_Template.reg
LikeLike
In VS2019 it works if you create an VSIX project and add the .pkgdef file as an asset.
It also needs the pkgfile to be in a .reg format e.g. the line
“Priority”=100
needs to be
“Priority”=dword:00000100
I also have this (don’t think it is necessary):
“Disabled”=dword:00000000
LikeLike