Integrating GAC Assemblies with Visual Studio
Originally published: 19 February 2006
Updated: 20 May 2010
The question comes up all the time about how to get documentation and debugging support for GAC assemblies into Visual Studio (VS). This article will discuss the steps it takes to make this happen. The steps are straightforward once you understand what goes on behind the scenes.
Visual Studio and the GAC
The first thing that must be understood is the fact that VS does not reference assemblies from the GAC. If you open the Add References dialog in VS you will notice that none of the assemblies are actually coming from the GAC. Instead the .NET framework assemblies are pointing to C:WindowsMicrosoft.NETFrameworkvx.y.z while SQL and Office point to different directories. VS ALWAYS refers to assemblies from regular directory paths. At runtime the CLR will load GAC assemblies from the GAC but this is independent of VS.
The next thing to understand is that the GAC only supports storing assemblies. Documentation and debug files, along with configuration or other files, can not go in the GAC. Therefore if VS did use the GAC it still would not have access to the documentation or debug files of assemblies. So how do we get VS to recognize these files?
All assemblies along with their debug (.pdb) and documentation (.xml) files should be installed into a normal directory. This is in addition to placing the assemblies in the GAC. The target directory for these files is known as the assembly folder. It is this folder that you will point VS to. When VS loads an assembly it will automatically pick up any .pdb and .xml files in the same directory provided they match the assembly. If VS loads the .pdb file then debug information is available for the assembly. If VS loads the .xml file then Intellisense will display documentation about the members of the assembly. This is automatic.
So, when installing your GAC assemblies, copy the original assemblies, the associated .pdb files and the .xml documentation files to a normal directory. Then install the assemblies into the GAC. Now all you need to do is have your users point VS to the appropriate folder and they’ll get debugging and Intellisense support.
Registering Your Assembly Folder
I know what you are thinking. “But SQL, Office and .NET itself automatically shows up in Add References dialog. My assemblies do not even though I put them into the GAC. What is going on?” Please refer to what I said in the first part of this article: “VS ALWAYS refers to assemblies from regular directory paths.” The Add References dialog IS NOT populated from the assemblies in the GAC. VS must be told where the assemblies come from. Enter the Registry.
When VS wants to get the assemblies for the Add References dialog it will query the Registry for the keys under HKLMSoftwareVisualStudio8.0AssemblyFolders. Each key under the main key represents an assembly folder. The actual name of each key is irrelevant but the default value of the key must be the full path to an assembly folder. VS will add all the assemblies from the assembly folder to the Add References dialog.
Update: Beginning with Visual Studio 2008 the way VS finds assemblies has changed. The aforementioned registry key still works but a new path is also used (although this has not been formally confirmed). For VS2008 the following key can also be used: HKLMSoftwareVisualStudio9.0ExpAssemblyFolders . For VS2010 the path is HKLMSoftwareVisualStudio10.0ExpAssemblyFolders.
Therefore if you want your assemblies to automatically show up in the dialog all you need do during installation is to add a new subkey under the base key, given earlier, and specify the full path to your assembly folder as the default value. VS will automatically list your assemblies when the dialog is displayed. Assuming that you followed the steps given earlier in the article the user will also automatically have debugging and documentation support.
Here is an example of what you might have in the Registry:
HKLMSoftwareMicrosoftVisualStudio8.0AssemblyFoldersAvalonAssemblies => (Default): C:WindowsMicrosoft.NETWindowsv6.0.4030
HKLMSoftwareMicrosoftVisualStudio8.0AssemblyFoldersKraken => (Default): C:Program FilesKrakenv2.1.0
Multi-targeting in Visual Studio
Beginning with VS2008 you can now target different versions of the framework. This introduces an issue for assembly references. Some references can only be used with certain versions of the framework. The existing registry key doesn’t differentiate between the (now) large number of frameworks available so a new set of keys are used. Under HKLMSoftwareMicrosoft.NETFramework is a new set of directories that VS will also search. Through some simple (aka not official) testing it turns out that VS will search a bunch of different paths. Under the key it searches AssemblyFolders. Additionally it will search for <version>AssemblyFoldersEx under the version of the framework you are targeting. This is how VS can filter out assemblies that are not valid for a particular framework.
A word of caution here: if you are running x64 of Windows then some of these keys reside under the x64 tree (HKLMSoftware) while others reside under the x86 tree (HKLMSoftwareWow6432Node). VS will search both sets. Also, as an aside, note that VS will check in HKCU as well.
Here is an example of what would be searched if you are targeting the v4 framework in VS2010
Putting It All Together
So, in summary, to expose your GAC assemblies, debug files and documentation files to VS do the following.
- Create a regular directory for your files.
- Copy the assemblies, debug files and documentation files to the directory.
- Install the assemblies into the GAC.
- Create a new subkey in the registry in the appropriate version-specific key (HKLMSoftwareMicrosoft.NETFramework<version>AssemblyFoldersEx).
- Set the default value of the key to the directory created in step 1.
When I say that VS does not use the GAC please be aware that it might but not in a manner in which we can take advantage of it here. You will also notice that the core framework is not listed in the Registry. Whether the framework is hard-coded into VS or whether it uses a different techique I can not say for sure. Nevertheless it is not extensible for our purposes.