by
Alan Shi
This article can be found here, we only host it, in case the link is down, and our customers want to immediately read it.
We suggest you check the live article, for any updates.
When installing an assembly to the GAC, Fusion provides a mechanism for the
installer to specify a traced reference count on the assembly being installed.
The idea is that if the same assembly is installed multiple times by different
clients, the assembly is not removed until all of the clients that installed the
assembly have explicitly requested uninstall. Without such a feature, you could
run into scenarios where assemblies are prematurely uninstalled. For example:
two applications install the same shared assembly to the GAC; one application is
uninstalled, and the shared assembly is removed even though another app still
needs it.
The reference counts Fusion provides are called “traced” reference counts,
because unlike COM reference counts, which simply record the number of
outstanding clients, an installer is allowed to specify information identifying
who needs the particular assembly. There are different kinds of traced reference
counts that an installer can provide, such as a filepath, or an opaque string
that is installer-specified. Gacutil allows you to specify traced reference
counts in an install command-line via the /r option.
You can read more about traced reference counts in this
gacutil MSDN document. There is also information about traced reference count in
our support
article describing the unmanaged Fusion API.
When you install your assembly using MSI
(which is the recommended approach for retail installs), there is no need to
specify a traced reference count for your assembly, because MSI has its own
internal reference counting mechanism. When Fusion is asked to uninstall an
assembly from the GAC, it will check if there are any outstanding traced
reference counts. If there aren't any traced reference counts, Fusion will
call a Windows Installer API to determine whether or not MSI holds a reference
on the assembly. If any reference count (traced reference count, or MSI
reference count) exists, the assembly will not be uninstalled.
If you try to uninstall an assembly in the GAC using “gacutil -u”, you may
see a message indicating that some traced reference count remains on the
assembly, and gacutil will output the information about the pending traced
reference count. In order to uninstall it, you must remove all the traced
reference counts. For MSI-installed assemblies, this is only possible by
uninstalling the MSI package that installed the assembly via Add/Remove
programs.
Some customers have reported unusual cases where an assembly installed into
the GAC via gacutil without a traced reference count, can later not be
uninstalled via “gacutil -u“. When the uninstall is attempted, the following
message appears:
Unable to uninstall: assembly is required by one or more applications
Pending references:
SCHEME: <WINDOWS_INSTALLER> ID:
<MSI> DESCRIPTION:<Windows
Installer>
This message is informing the user that Fusion
thinks that Windows Installer holds a reference count on the assembly, yet this
information is clearly wrong because the assembly was never installed via
MSI.
If you encounter this problem, it is very likely
that you have run into an odd MSI registry corruption (at the time of this
writing, the cause is unknown). Without getting into a long-winded explanation
of how this registry corruption eventually results in the error message above,
the common cause of this is a bogus default value set under one (or both) of
the below registry keys:
[HKCU\Software\Microsoft\Installer\Assemblies\Global]
[HKLM\SOFTWARE\Classes\Installer\Assemblies\Global]
If these keys are not empty (e.g. they contain a
MSI descriptor value), then you have hit this situation, and you should be able
to fix the problem by clearing the default value. I can't guarantee that this
will always work, but it has definitely been our experience that this is the
most common source of this problem.
(This tip comes courtesy of our resident MSI expert
on the Fusion team, Roberto Sciore).