Click here to Skip to main content
13,589,862 members
Click here to Skip to main content
Add your own
alternative version


32 bookmarked
Posted 10 Aug 2007

Automatically GAC an assembly after a build and include debug info.

, 10 Aug 2007
Rate this:
Please Sign up or sign in to vote.
This describes how to modify a VS project to automatically GAC an assembly after a build and optionally include debug info.


This article describes how to configure a VS 2003 or 2005 project to automatically GAC an assembly after a build. It also describes how to move the debug information into the GAC.


I first used this technique a couple of years ago when working on projects with quite a bit of shared code. Most of the framework assemblies were put into the GAC for the projects to share. This became a useful technique for debugging the project in the same manner in which it would be deployed to production.

In a project file you can automatically GAC an assembly after a build by putting the following in the Post-Build event.
"C:\Program files\Microsoft Visual Studio 8\SDK\v2.0\Bin\GacUtil.exe" 
                            -i "$(TargetPath)"

Obviously if you're in a team environment, you'll probably want to use environment variables like %ProgramFiles%. To the best of my knowledge there is no environment variable pointing to the full path. If you open a VS command prompt this directory is added to the path variable, but oddly that's not available during a build.
Note: for 2003 the path is C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin. After adding this, you need to address the opposite side of the problem: Ungacing before a build. In the pre-build event put:

"C:\Program files\Microsoft Visual Studio 8\SDK\v2.0\Bin\GacUtil.exe" 
                            -u $(TargetName)

Most of you could have probably figured this out on your own, if you haven't already. The problem I ran into is that once I had gaced an assembly, the debug info didn't go with it, no matter how I built the assembly. This is where things get sortof weird. The GAC is actually a top secret series of folders under the windows\assembly folder. If you pull this folder up in Explorer, you get a "special" window that allows you to perform GAC administration (e.g. drag and drop install, delete, etc.). If you open a command prompt and go to the same directory you'll see something like this:

Volume in drive C has no label.
 Volume Serial Number is D43F-9977

 Directory of C:\WINDOWS\assembly

10/06/2006  01:22 PM    <DIR>          GAC
10/16/2006  04:25 PM    <DIR>          GAC_32
11/20/2006  01:42 PM    <DIR>          GAC_MSIL
07/11/2006  09:44 AM    <DIR>          NativeImages1_v1.1.4322
10/19/2006  05:07 PM    <DIR>          NativeImages_v2.0.50727_32
11/20/2006  01:42 PM    <DIR>          temp
11/20/2006  01:42 PM    <DIR>          tmp
               0 File(s)              0 bytes
               7 Dir(s)  11,621,462,016 bytes free

This is the super-secret GAC area where things actually go. The GAC folder is for .NET 1.1 assemblies, the GAC_MSIL is (mostly) for .NET 2.0 assemblies. If you go under the GAC_MSIL folder ("cd GAC_MSIL" for those too young to remember DOS commands) you'll see a series of directories with the same names as the assemblies in your GAC (at least the 2.0 assemblies) As an example we'll play with System.Xml. enter the System.Xml directory ("cd System.Xml") and you'll see this:

Volume in drive C has no label.
 Volume Serial Number is D43F-9977

 Directory of C:\WINDOWS\assembly\GAC_MSIL\System.Xml

10/16/2006  04:24 PM    <DIR>          .
10/16/2006  04:24 PM    <DIR>          ..
10/16/2006  04:24 PM    <DIR>
               0 File(s)              0 bytes
               3 Dir(s)  11,621,388,288 bytes free

This is how multiple versions of the same assembly can be in the GAC at the same time. The folder name is constructed as follows: %VersionInfo%_%CultureInfo%_%PublicKeyToken%. Therefore if you've gaced 1.0 and 1.1 of an assembly, there will be two folders here. I assume the token is there in case two vendors put out assemblies with the same name, but I'm guessing here. Moving on. Going into this folder you'll find your long lost assembly hidden away.

Volume in drive C has no label.
 Volume Serial Number is D43F-9977

 Directory of C:\WINDOWS\assembly\GAC_MSIL\System.Xml\

10/16/2006  04:24 PM    <DIR>          .
10/16/2006  04:24 PM    <DIR>          ..
10/16/2006  04:24 PM         2,035,712 System.XML.dll
               1 File(s)      2,035,712 bytes
               2 Dir(s)  11,621,388,288 bytes free

If you want debug info for your gaced assembly, the PDB needs to go here. And there's no automatic way to get it here. I generally try to keep pre and post build events fairly generic, but in this case I don't know how to do it without some sort of helper program. If you put the following command in your post build event you can copy the PDB here:

copy "$(TargetDir)$(TargetName).pdb" "C:\windows\assembly\GAC_MSIL

Replacing $AssemblyName$ with your assembly name, etc. (The $() macros are actual macros understood by msbuild, don't change those). The $AssemblyName$, $VersionNumber$, and $PublicKeyToken$ variables are NOT macros. You need to explicitly define these or create a helper program to discover them. I have in the past written a little command line utility to parse assemblies information and put their debug information into the GAC. That's a little beyond the scope of this post, but I might cover it later. Here's the gotchas. Microsoft apparently did not want you messing with these directories directly, so they've protected them. You "cannot" access them in any way except the command line. This means you can't whip out a little vbscript file to do it, you can't do it in C#, you can "only" do it through the command line or a .bat file. (Believe me, I've tried). So if you try to automate this, the best you can do is to write out a batch file then run it. Sortof clumsy, but it works. I've found that this method doesn't work so well if you want to build and GAC more than one version of an assembly. In this instance I did away with the prebuild event (unregister) and changed the post-build event to:

"C:\Program files\Microsoft Visual Studio 8\SDK\v2.0\Bin\GacUtil.exe" 
                            -i "$(TargetPath)" /f

Which means force a replacement if there is an existing version in the GAC. This allowed me to build 2.1 without removing 2.0 (just in case anything depended on 2.0).


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Web Developer
United States United States
I started out in life as a musician. I started playing the violin at age 4, and I've never really stopped. Even when I fully believed my life would be spent as a musician, I had a fondness for computers.

At age 11 my parents bought our first computer, a Texas Instruments TI 99/4A. This is where I learned BASIC, spending countless hours typing in game source code from the back of magazines and various books.

I began seriously learning about the IBM when I was 16 and accidently trashed MS-DOS 4 on my Dad's new 386 trying to remove 688 Attack Sub. The phone call to tech support went something like "I've gotta get it working, my Dad's gonna KILL me!".

After a couple years of living the musician life in college, I found it wasn't condusive to maintaining scholarships. I took a few years off, regrouped, and refocused on programming, finally completing a degree.

I've been actively working in the IT field as a programmer since 1997, having just been sacked from my warehouse job at Elek-Tek when it declared bankruptcy. The first part of my career was as a C++ programmer, with a brief foray into Java in 2000, moving into ASP web development in 2001 and C# ASP.NET development in 2003.

I'm a Microsoft MCP, and still actively participate in the local music community.

You may also be interested in...


Comments and Discussions

GeneralGreat first article Pin
Josh Smith10-Aug-07 13:52
mvpJosh Smith10-Aug-07 13:52 
Congrats on your first CP article! Smile | :)

Have you tested this on Vista? I'm curious if Vista's wretched UAC screws this up.


My WPF Blog[^]
Without a strive for perfection I would be terribly bored.

GeneralRe: Great first article Pin
justinjones11-Aug-07 5:29
memberjustinjones11-Aug-07 5:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.180618.1 | Last Updated 10 Aug 2007
Article Copyright 2007 by Justin.Jones
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid