Hi all,
I've been struggling with an assembly loading problem for some time now, and I figured it was finally about time to ask someone about it.
I'm building an application that integrates data between two different versions of an accounting application. Both versions of the accounting application are managed/unmanaged hybrids with the high-level interfaces implemented in .Net, the deep internals implemented in C++, and an interop layer in managed C++. My integration application loads some of the managed dlls from each application and uses some common interfaces to transfer data between them.
Within my integration application, each version of the accounting application is loaded in its own AppDomain. This allows me to load different versions of the same .Net assembly within the same process. The problem is that some of the assemblies depend on the interop assemblies which in turn depend on unmanaged dlls. It seems like even though the assemblies are being loaded from different AppDomains, there are collisions when each tries to load different versions of the same unmanaged dlls.
A (very) simplified example:
Integrate.exe loads DataAccess.dll (V1) assembly into AppDomainV1 and DataAccess.dll (V2) into AppDomainV2. Each version of DataAccess.dll depends on its own version of Interop.dll (the managed C++ interop layer) which in turn depends on its own version of UnmanagedDataAccess.dll.
To illustrate:
Integrate.exe
AppDomainV1 loads:
DataAccess.dll (V1), Interop.dll (V1), UnmanagedDataAccess.dll (V2)
AppDomainV2 loads:
DataAccess.dll (V2), Interop.dll (V2), UnmanagedDataAccess.dll (V2)
Unfortunately, it seems that I have a first-come, first-serve situation for UnmanagedDataAccess.dll. If AppDomainV1 loads it first, it uses the V1 version, and AppDomainV2 fails to load (see exception below). If AppDomainV2 loads it first, it uses the V2 version, and AppDomainV1 fails to load.
Here's the exception I'm getting:
System.IO.FileLoadException: A procedure imported by 'c:\AcctV2\Interop.dll, Version=2.0.2546.29630, Culture=neutral, PublicKeyToken=null' could not be loaded.
File name: 'Interop.dll, Version=2.0.2546.29630, Culture=neutral, PublicKeyToken=null' ---> System.Runtime.InteropServices.COMException (0x8007007F): The specified procedure could not be found. (Exception from HRESULT: 0x8007007F)
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
I was hoping that using AppDomains would solve this problem, and they do for pure managed assemblies, but if those assemblies have unmanaged dependencies, you are right back in good ol' DLL hell.
Any suggestions
--Matt

Unmanaged dll hell and AppDomains
Muhammad Adel
dustin034
Thanks again for the input.
I took a look at the DLL/COM redirection article you pointed me to and the whitepaper it references. I might be missing something, but this doesn't seem to help with my situation. In my situation, I need a single process to load two different versions of a particular unmanaged DLL and/or COM component. The DLL/COM redirection you referred to seems to allow two separate processes to load different, private versions of shared Win32 and COM global components.
From the whitepaper: "Side-by-side sharing allows multiple versions of the same component (COM or Win32R) to run at the same time in different processes."
Am I missing something I didn't see anything that helps solve the problem that I'm trying to do this from the a single process...
Thanks again...
--Matt
BLACKDOG2
nabeelfarid
Thanks for the response.
I think that is the direction we are looking to go. Unfortunately while we can rename the dlls for the unmanaged dependencies we own, we employ a couple of third-party components who's dlls we don't own. If we take a new version of the third party dll with the same name as the previous version (which is the case), we are in trouble. We may be able to work around this issue for the current third party dlls, but it is a fragile solution, and it might bite us in the future with other third party components.
I'm disappointed that AppDomains don't solve the problem for unmanaged dlls. I guess I understand why they don't, but it seems like AppDomain are essentially broken for a key segment of use scenarios - anything involving managed/unmanaged hybrid solutions with unmanaged dependencies.
Thanks again...
--Matt
glenna
Leonard Lee