Here's a fun one:
Our Windows Forms application uses the Crystal Reports .NET assemblies,
which we ship and reference privately from our application folder.
These assemblies have strong names. Works great - most of the time.
Other vendors of Crystal applications will often register these DLLs in
the GAC, which should be fine. The problem is that Crystal Decisions
sometimes does not change the assembly version when releasing DLL
updates. So, what happens is our application loads, binds to a
particular DLL version, the CLR loader finds this exact version in the
GAC and loads from the GAC instead of our app folder. This is
problematic as the "sub-versions" are not compatible with each other
and our app crashes.
This is new in the 2.0 framework. Under 1.1, our app would always load
the private assembly.
Our question: How do we force the CLR loader to ignore the GAC and
always load these assemblies from the app folder? I've experimented
with many config file combinations - to no avail. Also ran
FUSLOGVW.exe, which happily announced that the assembly was found in
the GAC - no need to look further.
Crystal Decisions was no help.
Ideas on this? Something I might be missing? Thanks!
Jon
smc750 - 10 May 2006 15:03 GMT
According to documentation and what I have used in the past you can use
System.Reflection.Assemby.Load or LoadWithPartialName passing in only the
assembly name, not the full name. When loading an assembly with a partial
name the CLR should automatically check for the assembly in the application
directory first. Make sure you do not have a <qualifyAssembly> element in
your application config file.
Hope this helps.
smc750
www.certdev.com
>Here's a fun one:
>
[quoted text clipped - 25 lines]
>
>Jon

Signature
smc750
www.certdev.com
pdxfilter-google@yahoo.com - 10 May 2006 20:13 GMT
SMC,
Thanks for the reply. We've tried Assembly.Load(). Here's what
happens:
1. Runtime finds the DLL in our private folder.
2. Runtime extracts strong name info from said DLL
3. Runtime binds to DLL in the GAC with the same strong name, ignoring
the private DLL.
This is great if the private DLL and the GAC DLL are the same. In the
case of Crystal Reports, they're not, even though they have the same
assembly version.
We're still looking for a workaround, hack or not...
Thanks again!
Jon
smc750 - 10 May 2006 22:48 GMT
Try LoadWithPartialName
>SMC,
>
[quoted text clipped - 15 lines]
>
>Jon

Signature
smc750
www.certdev.com
pdxfilter-google@yahoo.com - 11 May 2006 19:19 GMT
SMC,
Thanks for the reply. LoadWithPartialName does not pick up the private
assembly. It still pulls from the GAC.
I've heard (but not tried) that Load(byte[] assembly) will parse out
the strong name and still pull from the GAC, ignoring the code image
passed in.
Unfortunate DLL hell issue, since it means that apps that use private,
strong named assemblies are at risk for being broken by what other apps
may put in the GAC. That's what's happening to our app, post .NET 2.0.
Jon
David Levine - 12 May 2006 09:59 GMT
There was a change made in 2.0 about binding policies that caused this; I
don't much care for it either. It used to be that if you used LoadFile it
would ignore policy and bind to the file, but that changed; if the same
assembly identity is in the GAC then that it is the one that gets used. This
blog explains it:
http://blogs.msdn.com/junfeng/archive/2004/11/03/252033.aspx
IMO Crystal Reports should change the version number for each released
assembly version.
The only workaround I know of is to host the runtime yourself (
http://msdn2.microsoft.com/en-us/library/9x0wh2z3(VS.80).aspx) and override
the CLR assembly manager to establish your own loading and binding rules
using the IHostAssemblyManager interface
(http://msdn2.microsoft.com/en-us/library/ms164458(VS.80).aspx). There's a
book that describes all these interfaces....
...or don't use Crystal Reports.
> Here's a fun one:
>
[quoted text clipped - 25 lines]
>
> Jon