The GAC

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

When you view the GAC in windows explorer, it shows it as a special type of
view. It also tells you if you try to delete an assembly that is a dependency
of an installed application, but if nothing is dependent on it, then it will
delete OK. If it won't delete as it's needed by an application - is there any
way of finding out which one?
 
Bonj,

That would be hard to do, because applications don't have to register
themselves as needing to use particular components in the GAC. It's
analagous to trying to find out what applications use a particular COM
component. The best you could do is search all managed assemblies on the
machine, and see which one has a reference to the type in the GAC.

Hope this helps.
 
So if it doesn't know *which* one uses it, how does it know *whether* any
applications use it?
COM doesn't know this, for its components. You can do "regsvr32 any.dll /u"
on a COM server that is used by dozens of essential applications installed on
the machine, and as long as they're not using the COM object at that
particular moment in time, then it will quite happily unregister it and you
will be able to delete it.
But just to test -
Create a GAC-able component, and without creating any applications that
depend on it, use gacutil.exe to put it into the GAC. Now, create another
GAC-able class library, and add a project that depends on it. Add a third
project as the setup project, and tell it to put the class library in the
GAC. Install it. Then go to the GAC and try to delete the two components. It
will let you delete the first, but will tell you that 'Assembly ~~~~ could
not be deleted as it is required by other applications' for the second.
And I fail to believe that this is due to the reference count, as if you
right click on any component in the GAC and click properties, it will tell
you that its reference count is 1 - it is *always* 1, no matter whether, or
how many, other applications are depending on it - it's never zero, and never
more than 1.
It must have some way of knowing whether to put up a message box or not,
because it always makes that decision correctly.
Do you see what I mean, and how it's different to COM?



Nicholas Paldino said:
Bonj,

That would be hard to do, because applications don't have to register
themselves as needing to use particular components in the GAC. It's
analagous to trying to find out what applications use a particular COM
component. The best you could do is search all managed assemblies on the
machine, and see which one has a reference to the type in the GAC.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bonj said:
When you view the GAC in windows explorer, it shows it as a special type
of
view. It also tells you if you try to delete an assembly that is a
dependency
of an installed application, but if nothing is dependent on it, then it
will
delete OK. If it won't delete as it's needed by an application - is there
any
way of finding out which one?
 
Bonj,

This makes sense. If there are other components in the GAC that
reference it, then the GAC can detect this. However, there is no
requirement that a component outside of the GAC can't use a component that
is in the GAC. Because of this, you don't always know what is using it.

Also, it is possible to register applications with the framework (if you
go to the .NET administration tool, you will see what I mean, there is a
section called "configured applications" I believe) then the view on the GAC
might be checking that.

Other than that though, you really don't know what could be using
something in the GAC, and you always run the risk of breaking an application
on the machine if you remove it.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bonj said:
So if it doesn't know *which* one uses it, how does it know *whether* any
applications use it?
COM doesn't know this, for its components. You can do "regsvr32 any.dll
/u"
on a COM server that is used by dozens of essential applications installed
on
the machine, and as long as they're not using the COM object at that
particular moment in time, then it will quite happily unregister it and
you
will be able to delete it.
But just to test -
Create a GAC-able component, and without creating any applications that
depend on it, use gacutil.exe to put it into the GAC. Now, create another
GAC-able class library, and add a project that depends on it. Add a third
project as the setup project, and tell it to put the class library in the
GAC. Install it. Then go to the GAC and try to delete the two components.
It
will let you delete the first, but will tell you that 'Assembly ~~~~ could
not be deleted as it is required by other applications' for the second.
And I fail to believe that this is due to the reference count, as if you
right click on any component in the GAC and click properties, it will tell
you that its reference count is 1 - it is *always* 1, no matter whether,
or
how many, other applications are depending on it - it's never zero, and
never
more than 1.
It must have some way of knowing whether to put up a message box or not,
because it always makes that decision correctly.
Do you see what I mean, and how it's different to COM?



Nicholas Paldino said:
Bonj,

That would be hard to do, because applications don't have to register
themselves as needing to use particular components in the GAC. It's
analagous to trying to find out what applications use a particular COM
component. The best you could do is search all managed assemblies on the
machine, and see which one has a reference to the type in the GAC.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bonj said:
When you view the GAC in windows explorer, it shows it as a special
type
of
view. It also tells you if you try to delete an assembly that is a
dependency
of an installed application, but if nothing is dependent on it, then it
will
delete OK. If it won't delete as it's needed by an application - is
there
any
way of finding out which one?
 
The GAC uses a different mechanism for doing usage counting. It doesn't use
a simple up/down numeric counter to indicate if a component is in use.
Instead, it uses a data structure called a TraceReference. This contains
information about the application that installed the component to the GAC.
There are a number of options that it can have, but what it boils down to is
it contains some user-defined data (usually a friendly readable string) and
an ID that uniquely (hopefully) identifies the application that installed
it.

What makes this interesting is this: you can install the component many
times, and if it is installed using a key that is a duplicate of the key by
which it was already installed, then the usage count does not increase.
Likeiwise, you can uninstall the component many times, but the install acts
like a two-phase uninstall - the first phase uninstalls the trace reference
(and it has to be an exact match based on the unique ID), and the second
phase checks if all trace references have been removed. Only if all
references are removed does the component actually get uninstalled.

The result is that there is no way to determine which applications are using
a particular assembly in the GAC, but it is possible to avoid the worst of
the DLL hell problem by using trace references properly. The downside is
that as best as I can tell these references are not some magic that
guarantees that each application will get a different reference valiue -
instead, it relies on convention. There's nothing to stop one application
from using the same unique ID as another application. It is possible that a
rogue app will misuse an ID, but the app would have to be malicious to
deliberately do this. The other downside is that (as best as I can tell) it
requires installers to use a unique ID for each app that installs the same
component into the GAC for this to be effective.

I think it's too soon to tell if this approach will work well over time.

This link describes this in more detail.

http://weblogs.asp.net/junfeng/archive/2004/09/13/228651.aspx




Bonj said:
So if it doesn't know *which* one uses it, how does it know *whether* any
applications use it?
COM doesn't know this, for its components. You can do "regsvr32 any.dll
/u"
on a COM server that is used by dozens of essential applications installed
on
the machine, and as long as they're not using the COM object at that
particular moment in time, then it will quite happily unregister it and
you
will be able to delete it.
But just to test -
Create a GAC-able component, and without creating any applications that
depend on it, use gacutil.exe to put it into the GAC. Now, create another
GAC-able class library, and add a project that depends on it. Add a third
project as the setup project, and tell it to put the class library in the
GAC. Install it. Then go to the GAC and try to delete the two components.
It
will let you delete the first, but will tell you that 'Assembly ~~~~ could
not be deleted as it is required by other applications' for the second.
And I fail to believe that this is due to the reference count, as if you
right click on any component in the GAC and click properties, it will tell
you that its reference count is 1 - it is *always* 1, no matter whether,
or
how many, other applications are depending on it - it's never zero, and
never
more than 1.
It must have some way of knowing whether to put up a message box or not,
because it always makes that decision correctly.
Do you see what I mean, and how it's different to COM?



Nicholas Paldino said:
Bonj,

That would be hard to do, because applications don't have to register
themselves as needing to use particular components in the GAC. It's
analagous to trying to find out what applications use a particular COM
component. The best you could do is search all managed assemblies on the
machine, and see which one has a reference to the type in the GAC.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bonj said:
When you view the GAC in windows explorer, it shows it as a special
type
of
view. It also tells you if you try to delete an assembly that is a
dependency
of an installed application, but if nothing is dependent on it, then it
will
delete OK. If it won't delete as it's needed by an application - is
there
any
way of finding out which one?
 
Back
Top