7. GAC References
Microsoft Installer understands .NET assemblies and the GAC. An MSI file can contain shared assemblies and when the MSI file is installed the shared assemblies will be installed into the GAC; when the MSI is uninstalled the assemblies will be removed from the GAC. Is this what you want? No, not necessarily. The reason is that a shared assembly will be used by one or more applications. The MSI files for those applications will install the same shared assembly into the GAC. If one of the applications is uninstalled it could remove the shared assembly from the GAC and so the remaining applications will not run.
Of course, this is not the case in practice because .NET has a mechanism to
prevent this from happening. .NET handles this through GAC references. In simple
terms, each time you install an assembly and indicate that reference counting is
used, the reference count is incremented; each time you uninstall an assembly
and indicate that reference counting is used, the reference count is
decremented; when the reference count falls to zero, the assembly is removed
from the GAC. gacutil uses the -r switch to handle
reference counting and this switch can be combined with other switches. To
install an assembly you use -ir:
Here, <scheme> determines how the assembly was installed and can
be one of: UNINSTALL_KEY, which means that the assembly can be
uninstalled through the control panel Add/Remove Programs and so
uninstall information is stored in the registry; FILEPATH, which
means that a separate process is used to uninstall the assembly; or OPAQUE,
which indicates that you will uninstall the assembly in some other way. The
<id> parameter depends on the <scheme> parameter and
can contain the name of the registry key with uninstall information or the path
to the uninstall application. <description> is whatever you choose.
7.1 Adding a GAC Reference
In this example, use the process, library and key file from the previous examples. Compile the library and install it with:
This adds one reference for the assembly, the assembly could be installed for
another application but to increment the reference count the <id>
would have to be a different value to "myData". For example, add
another reference with:
To list the references use the -lr switch, this can take a
filter, for example:
Microsoft (R) .NET Global Assembly Cache Utility. Version 1.1.4322
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.
The Global Assembly Cache contains the following assemblies:
lib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=ede6789fb0b13219, Custom=null
SCHEME: <OPAQUE> ID: <myData> DESCRIPTION : <my installer info>
SCHEME: <OPAQUE> ID: <myData2> DESCRIPTION : <my installer info>
The cache of ngen files contains the following entries:
Number of items = 1
You can also confirm that the assembly is installed with references by selecting the assembly's properties in Windows Explorer:
|
|
.NET Version 3.0 The property page for assemblies in the GAC under .NET version 3.0/2.0 do not show the number of references. The only way to get this information is to use
gacutil -lr. |
To
uninstall an assembly you have to provide the complete display name (or the
short name if you feel confident that there are no other assemblies with the
same short name), and the <scheme> and <id>.
Bizarrely,
you also have to include the <description> parameters that you used when installing the
assembly:
(The description parameter is required but does not have to be the same as the
string you used to add the assembly to the cache.) When you uninstall an
assembly, read the output from gacutil carefully, you will see that
it lists the references that have been removed, the pending references (ie
references that have not been removed) and it will list the number of assemblies
removed. The first time you call gacutil -ur Number of
assemblies uninstalled will be zero because there will still be a reference
on the assembly.
This will decrement the reference count and you can confirm this with Windows
Explorer or gacutil. If you want to remove the assembly without
using references you can use the -uf switch without the reference
information (again, either the full name, or the short name):
There is another value for <scheme> and it is the
value that will be used most often: WINDOWS_INSTALLER. This
indicates that Windows Installer was used to install the assembly and therefore
you can only uninstall the assembly using Windows Installer. If you try to
uninstall the assembly with gacutil it will reject the
WINDOWS_INSTALLER scheme.
| I hope that you enjoy this tutorial and value the knowledge that you will gain from it. I am always pleased to hear from people who use this tutorial (contact me). If you find this tutorial useful then please also email your comments to mvpga@microsoft.com. |
Errata
If you see an error on this page, please contact me and I will fix the problem.