Determine which assembly references are not from the base framework...

  • Thread starter Thread starter Nathan Baulch
  • Start date Start date
N

Nathan Baulch

I'm looking for the best way to determine which assembly dependencies are
not part of the base framework and which are third party libraries.

My application stores add-on DLL's in a DB for transparent distribution to
all clients. Obviously when loading DLLs into the DB, it is necessary to
recursively traverse the dependency tree and pull in any that are not part
of the base framework.

I am currently achieving this by checking against a hard coded array of
strong names but I am thinking that there must be a better way.


Nathan
 
If there's a better way I have not found one yet. We check against some
well-known names, such as mscorlib, and assemblies that start with "System".
I like your idea of method against a well-known strong name.

If your add-ons are supposed to be completely self-contained then you could
check to see if the assembly is in the GAC, or located in the same directory
(or a subdirectory) of the addin; by itself this is not enough but you might
apply some custom rules such as directory location as a filter.

Do you check for circular references in the dependency tree? I've found
there are a number of them.
 
If there's a better way I have not found one yet. We check against
some well-known names, such as mscorlib, and assemblies that start
with "System". I like your idea of method against a well-known strong
name.

I think I have found a better way (simpler, faster, version independent),
for my purposes anyway.

After having a closer look, there are only two different public key tokens
between all the DLLs in both the GAC and the
%SystemRoot%\Microsoft.net\Framework\v1.1.4322 directory. Thus all I have to
do is check the public key token on each dependency against those.

PublicKeyToken=B77A5C561934E089
PublicKeyToken=B03F5F7F11D50A3A

Here is a simple non-recursive example:

Assembly myAssembly = Assembly.LoadFile(@"c:\myAssembly.dll");
foreach(AssemblyName dependency in
myAssembly.GetReferencedAssemblies())
{
string token = BitConverter.ToString(
dependency.GetPublicKeyToken());
if(token != "B7-7A-5C-56-19-34-E0-89"
&& token != "B0-3F-5F-7F-11-D5-0A-3A")
{
Console.WriteLine("{0} not part of framework",dependency.Name);
}
}

I haven't checked yet, but I would assume that the framework assemblies
retain their public key token between framework versions/service packs/etc.
If your add-ons are supposed to be completely self-contained then you
could check to see if the assembly is in the GAC, or located in the
same directory (or a subdirectory) of the addin; by itself this is
not enough but you might apply some custom rules such as directory
location as a filter.

I can't use the existence in the GAC as an indicator
(Assembly.GlobalAssemblyCache property) as my add-ons often reference third
party libraries that are designed to reside in the GAC on development
machines but not clients.
I also found no way to trace the non-GAC location of a GAC referenced
assembly at runtime.
Do you check for circular references in the dependency tree? I've
found there are a number of them.

Sure do. I add each one to a collection and check to see if each new one has
already been encountered.


Nathan
 
PublicKeyToken=B77A5C561934E089
PublicKeyToken=B03F5F7F11D50A3A

Here is a simple non-recursive example:

Assembly myAssembly = Assembly.LoadFile(@"c:\myAssembly.dll");
foreach(AssemblyName dependency in
myAssembly.GetReferencedAssemblies())
{
string token = BitConverter.ToString(
dependency.GetPublicKeyToken());
if(token != "B7-7A-5C-56-19-34-E0-89"
&& token != "B0-3F-5F-7F-11-D5-0A-3A")
{
Console.WriteLine("{0} not part of framework",dependency.Name);
}
}

I haven't checked yet, but I would assume that the framework assemblies
retain their public key token between framework versions/service
packs/etc.

That's probably true. Rather then hardcode the strings, you could load up a
couple of well-known assemblies that belong to the Microsoft set (System.dll
is about as well-known as you will find), extract its token using
GetPublicKeyToken, and then do a binary comparison between that and the
assembly under test. I think there's a Microsoft public key and then the
ECMA public key. You could add assemblies to your list to load that you know
are not yours, such as Crystal Reports, Infragistics, etc. Course, you may
want to add those anyway, but it's your choice.
I can't use the existence in the GAC as an indicator
(Assembly.GlobalAssemblyCache property) as my add-ons often reference
third party libraries that are designed to reside in the GAC on
development machines but not clients.
I also found no way to trace the non-GAC location of a GAC referenced
assembly at runtime.
You can use the GAC COM interface for that. I've written some utils that
enumerate the gac and trace the location of the assemblies in the gac (and
compare the gac's on two machines). This link here has a managed wrapper to
those APIs that you can use to write your own.

http://weblogs.asp.net/junfeng/archive/2004/09/29/235620.aspx
 
Back
Top