ReferencedAssemblies and the gac

G

Guest

I'm dynamically compiling some code and adding needed referenced assemblies.
When I add references to DLLs using an absolute path there is no problem.
When I add *relative* references to the system DLLs there is, again, no
problem. But when I try to add a *relative* reference to 3rd party managed
DLLs that are present in the GAC I always get a:

Metadata file "xxx" could not be found

error. For example (assuming some third party "BarUtils" assemblies in the
GAC):

StringCollection refs = new StringCollection();
refs.Add("c:\dev\Foo\bin\debug\Foo.dll"); // This will work
refs.Add("System.Security.dll"); // This will work
refs.Add("BarUtils.Forms.Bar.dll"); // This will fail

What am I missing??

Thanks,
-- TB
 
M

Mattias Sjögren

What am I missing??

The compilers don't look in the GAC to find referenced assemblies. The
GAC is only used to resolve dependencies at runtime.


Mattias
 
G

Guest

Then why does the addition of a relative "System.Security.dll" work
correctly? Are the framework assemblies special-cased in the compiler?

That aside, though, perhaps you can point me to the objects/APIs that I
would need to resolve such an unqualified name to an exact location using the
GAC.

Thanks
-- TB
 
M

Mattias Sjögren

Thomas,
Then why does the addition of a relative "System.Security.dll" work
correctly? Are the framework assemblies special-cased in the compiler?

Yes, the compiler automatically checks the framework directory. See
the docs for the /lib compiler option for more details.


Mattias
 
G

Guest

Mattias Sjögren said:
Thomas,


Yes, the compiler automatically checks the framework directory. See
the docs for the /lib compiler option for more details.

Ah, yes, that would explain it!!

Anyway, as usually is the case, posting the question tends to stimulate my
thoughts enough to stumble on another solution. Here is what I'm currently
doing; this routine is used to convert a partial name reference to an
absolute location:

public static string FullReference(string relativeReference)
{
// First, get the path for this executing assembly.
Assembly a = Assembly.GetExecutingAssembly();
string path = Path.GetDirectoryName(a.Location);

// if the file exists in this Path - prepend the path
string fullReference = Path.Combine(path, relativeReference);
if (File.Exists(fullReference))
return fullReference;
else
{
// Strip off any trailing ".dll" if present.
if
(string.Compare(relativeReference.Substring(relativeReference.Length - 4),
".dll", true) == 0)
fullReference = relativeReference.Substring(0,
relativeReference.Length - 4);
else
fullReference = relativeReference;

// See if the required assembly is already present in our current
AppDomain
foreach (Assembly currAssembly in
AppDomain.CurrentDomain.GetAssemblies())
{
if (string.Compare(currAssembly.GetName().Name, fullReference,
true) == 0)
{
// Found it, return the location as the full reference.
return currAssembly.Location;
}
}

// The assembly isn't present in our current application, so attempt
to
// load it from the GAC, using the partial name.
try
{
Assembly tempAssembly =
Assembly.LoadWithPartialName(fullReference);
return tempAssembly.Location;
}
catch
{
// If we cannot load or otherwise access the assembly from the
GAC then just
// return the relative reference and hope for the best.
return relativeReference;
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top