views:

786

answers:

1

I have a project that comprises pre-build Dll modules, built some time in the past, using Visual Studio 9.

The EXE of the project is built now, using SP1 of Visual Studio 9.

When we deploy the EXE we don't want to require administrative access, so the C-Runtime has been bundled into the root of the application. The Dlls: MSVCRT90.DLL and their Manifest: Microsoft.VC90.CRT.manifest

Now, the EXE and latest versions of the runtime manifests are all in agreement - the application manifest asks for 9.0.30729.1 of msvcrt.dll, and the crt-manifest contains the entries confirming that msvcrt90.dll is version 9.0.30729.1

Now, a problem. A 3rd party DLL library used by our application was linked against the original msvcrt90.dll version 9.0.21022.8 and has an internal manifest to this effect.

On our development PCs where both versions of the VS9 CRuntime have been installed the app works. On "fresh" PCs where we install the app for the first time - the DLL fails to load.

Now, I have some cheats I can do - one is to revert the app to 9.0.2 - get the 9.0.2 DLLs off the original source media. This is undesirable as 9.0.3 is preferable. Or I try really hard to get a rebuild of the 3rd party library.

I am furthermore pretty certain that, on our development PCs, when the 3rd party library asks for the old dll it gets redirected to the new dll - they are binary compatible.

Application manifests and assemblies were meant to save us all from this kind of rubbish. It must be possible to edit the assembly manifest files so that both the exe and dll can load.

+1  A: 

I've never tried that but I think you can solve that with bindingRedirect in the manifest, I know that it works in the managed world.

See example (You will need to change the values for your version)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
  <windows>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <assemblyIdentity name="Your.Application.Name" type="win32" version="9.0.0.0"/>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" />
        <bindingRedirect oldVersion="9.0.20718.0-9.0.21022.8" newVersion="9.0.30411.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" />
        <bindingRedirect oldVersion="9.0.20718.0-9.0.21022.8" newVersion="9.0.30411.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.MFCLOC" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">
        </assemblyIdentity>
        <bindingRedirect oldVersion="9.0.20718.0-9.0.21022.8" newVersion="9.0.30411.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </windows>
</configuration>
Shay Erlichmen
This is very close to what ive been trying.Where and how do i place that XML however?My application has an embedded .manifest file, the documentation says that the bindingRedirections should be placed in an app.exe.config file. I have created the config file, placed it in my app folder and am not seeing any difference. im not sure its even being used.Perhaps I need to ensure the assemblyIdentity matches my apps manifest assemblyIdentiy fully.
Chris Becke
It needs to be inside the manifest, you can add your own declaration to the manifest generated by VS, I don't have VS here so I can't give you the exact method, but it somewhere under the project settings \ manfirst tool
Shay Erlichmen
Just some clarifications: If the EXE has the dependent assembly that must be redirected, the appropriate name for the local policy file is: application.exe.config - If it is a satellite dll that has a dependent assembly that needs redirection, then the policy file is called dllname.dll.2.config - Why .2 ? I dont know. But it has to be there.
Chris Becke