When you get beyond simple forms based applications and you're ready to tackle something a little more powerful, you might discover that you need programming tools that are more powerful too. This article is about GACUTIL - the Global Assembly Cache Utility.
About Visual Basic offers a series of articles about the Framework tools. Links to all of them, and an introduction to the .NET Framework tools, can be found at: Framework Tools - About the Tools. (Note ... The series is still incomplete as of this writing, however.)
Before you can understand what GACUTIL is and why it can help your system run better and faster, you first have to understand what a assemblies and "strong names" are. Although this article introduces the main ideas, I recommend reading the article about .NET assemblies here: The .NET Framework - Assemblies. Check out the article on strong names here: SN.EXE - The Strong Name Tool. The GAC is explained in the article about NGEN because the compiled native code assemblies that are produced by NGEN can be stored in the GAC.
GACUTIL is far less familiar than some other .NET Framework utilities to most programmers and, in fact, the target of the tool, the GAC (Global Assembly Cache) may not be familiar either. The GACUTIL tool is strictly for developers and even then will probably be used by a just a few of the programmers who concentrate on working out the special problems of deployment and configuration. In fact, most of the time assemblies are installed into the GAC using MSI - the Microsoft Installer - which actually has advantages over GACUTIL, especially in a production environment. (More about this below.) In general, only developers testing a system will use GACUTIL because it's faster and easier than creating and using an MSI install package for your system.
One of the ways you can check on results after running NGEN is to look in the GAC for the assembly. (Note, you have to use a Command Prompt window, not Windows Explorder). You can see the GAC folders, located at C:\WINDOWS\assembly, in this illustration:
Click Here to display the illustration
(Note: Microsoft, in their infinite wisdom, has decided to create a completely new GAC for use with Framework 4.0 (Visual Studio 2010). Assemblies for .NET 4.0 are in the C:\Windows\Microsoft.NET\assembly path. So both the new folder and the old ones are used, depending on the version of Framework that is being used. Fortunately, this change is more or less transparent for anything you will normally do.)
One other tip. You will still see articles that say you can copy an assembly directly to the GAC rather than installing it using GACUTIL or another method like MSI. Never do that. In the early versions of Framework, that might have been a good idea, but it's not anymore.
Because an assembly is the basic unit used by the .NET CLR (Common Language Runtime) for deployment, version control, security, type grouping and code reuse, when you run your VB.NET program, you're executing the assembly. An assembly will be an EXE or DLL file.
If you're new to .NET, you might think that Microsoft just thought up another name for executable files, but there's much more to assemblies. This is a huge part of the "secret sauce" that makes .NET a completely new and different world. An assembly consists of a manifest and one or more modules and/or files. The manifest makes an assembly "self describing" so the .NET CLR can make sure that it's the right one. Among other things, the manifest identifies the assembly, describes its security requirements, lists other assemblies it depends on, and lists all of the types and resources exposed by the assembly.
All this lets .NET accomplish what is called, "side by side execution". This is when multiple versions of the same assembly execute at the same time on the same PC or within the same process. Information in the assembly allows .NET to keep track of them. This is also why .NET programs don't have to be "registered" like they do using the previous idea, COM.
The GAC, however, helps your system keep things together, rather than keeping them apart. One of the advantages of COM was that programs anywhere could find a specific code module by looking up the location in the Windows registry. That way, you only needed one. And for many systems, that's what you do need: just one shared copy of the program for everything to use.
"But wait!" I hear you saying, "My program assembly isn't in any GAC, it's right there in the BIN directory with my application." Assemblies are of two types: application private and shared. The default is application private and only one application uses them. These are the assemblies that are in the application folder. A shared assemblies is meant to be used by more than one application. It has a globally unique name (called a strong name) and it must be located in the GAC. The purpose of GACUTIL is to list, install, and uninstall assemblies in the GAC.
Since the GAC is a central location for assemblies that need to be accessible by any application, Microsoft had to figure out how to avoid the situation that plagued the COM world: the "DLL Hell" 'version conflict' problem. .NET allows us to install two versions of the same assembly on the system without the risk on backward compatibility problems. It does this by requiring that shared assemblies have a "strong name" consisting of the name of the assembly, the version, a 64 bit hash of a public key (called a token) and the culture. To create a strong name for an assembly and generate a public/private key pair, you'll have to use another utility callled SN.exe. "SN" for "strong name". You can read the article about that here: SN.EXE - The Strong Name Tool
There's another problem that needs to be considered as well. What if the same assembly is installed into the GAC by more than one system? (For example, a printing program that is used by a number of different systems.) If, later on, one of the systems is uninstalled, the system would have to leave the assembly in the GAC so that the other system could continue to use it. For this reason, a "reference count" of how many times an assembly has been installed in the GAC is maintained ... if you request it using the correct command line switch /ir when using GACUTIL. The Microsoft Installer (MSI) maintains the reference count automatically. If you're just testing, you don't have use the reference count command line switch.
To see all the command line switches for GACUTIL, open a command window and type:
(Keep in mind that you still need to set the PATH correctly for this to work. If it doesn't, read the introduction article about how to set it.)
This should give you a listing of the various command line switches that you can use with GACUTIL.
To list assemblies installed in the GAC, use the /l command line switch.
A sample of the output is (the number in the Custom field is too long to fit the screen):
TestGAC, Version=126.96.36.199, Culture=neutral, PublicKeyToken=null,
Custom=5a00410050 ... 430031000000
TestGAC is the simple name of the assembly. If you include all of the parameters it's called a fully specified assembly name.
This contains some of the same information that you see in the custom view of the GAC that you see if you simply navigate there. (Again, the GAC is normally located at C:\WINDOWS\assembly or C:\Windows\Microsoft.NET\assembly.) You have to use a Command Prompt window to view it because Windows Explorer won't display it. Previous versions of Windows provided a custom version of Windows Explorer called - Can you predict it? - GAC Explorer - but current versions do not.
To install assemblies into the global assembly cache, first, use the strong name utility with a /i switch to create a strong name.
gacutil /i mySharedPgm.dll
You can also specify a text file that contains a list of assemblies to install in the GAC. Use the /il command line switch for that.
To uninstall an assembly from the global assembly cache, use the /u switch along with the name of the assembly without the .dll extension:
gacutil /u mySharedPgm
An uninstall only works if there are no other references to the same assembly. If there are, you should probably leave the assembly there.
The GAC can be a great idea for some assemblies, but not so great for others. Here's one rule to think about. Don't use GACUTIL if the application needs to be xcopy deployable on different machines since assemblies can't simply be copied when they're in the GAC, they have to be installed.