views:

191

answers:

1

We have a large MFC application that uses a number of DLLs. So far we have been using vcredist_x86.exe to install MFC and the CRT into the unmanaged side by side assembly cache (C:\Windows\WinSxS). When MFC/CRT is installed in this way, the application runs (on a clean XP machine).

According to the MSDN documentation, you can install MFC/CRT by copying the assembly files into the folder that your application is installed into. I have tested this with a simple MFC application and it works. But I am having problems getting our large MFC application to work using this approach.

It appears that the problem is caused by some of the DLLs having manifests that reference an earlier version of the CRT for example, one DLL contains the following manifest.

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50215.4652" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" /> 
</dependentAssembly>
</dependency>
</assembly>

We are copying version 8.0.50727.762 of the CRT assembly to our application's folder. As you can see this is a newer version of the CRT. But for some reason the OS loader fails to load the DLL with the above manifest. This does not happen when the same CRT assembly is installed in WinSxS. When I trace the loading using DependencyWalker I get the error LDR: LdrpWalkImportDescriptor() failed to probe c:\documents and settings\qatest\desktop\test\log4cpp.dll for its manifest, ntstatus 0xc0150002

It seems that the ability of the loader to load a newer version of an assembly does not work when using private side by side assemblies but it does work when the assemblies are installed into WinSxS.

Is there a solution to this?

+1  A: 

I think the answer comes down to the CRT Publisher Policy. Have a look at e.g. c:\windows\winsxs\Manifests\x86_policy.9.0.microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_f47e1bd6f6571810.manifest. This specifies that apps that reference older version of the CRT should load this version instead.

What you need to do to perform this redirection without installing vcredist is to either change the manifest, or to write a libraryX.dll.config (or possibly libraryX.dll.2.config) to redirect the binding.

See my post for an example config. Note that you don't need <publisherPolicy apply="no"/>; the publisher policy should be applied to close security holes.

Be sure to test on different versions of Windows, as SxS can work slightly differently.

Kevin Smyth