How to Add a Private Extension Gallery in Visual Studio 2017

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="">  
  <title type="text" />   
- <entry>  
  <title type="text">Highlight all occurrences of selected word</title>   
  <summary type="text">This extends the editor to highlight ....</summary>   
- <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="" xmlns:xsi="" xmlns="">  
  <References />   
  <Rating xsi:nil="true" />   
  <RatingCount xsi:nil="true" />   
  <DownloadCount xsi:nil="true" />   
- <entry>  

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.

Add Extension Gallery

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.

Visual Studio Installer

The first step is to create the project by selecting File –> New –> Project and then selecting VSIX Project under Extensibility.

Create VSIX Project

Next add a new .pkgdef file named CompanyPrivateGallery.pkgdef. Open the pkgdef file and add the following:

"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 localized DisplayName 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.

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)"
    &regedit /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.

"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

3 responses to “How to Add a Private Extension Gallery in Visual Studio 2017”

  1. 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 ‘&regedit /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 :
    & 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: 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


  2. 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
    needs to be
    I also have this (don’t think it is necessary):


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at

%d bloggers like this: