Adding a Configuration file for a VC++ DLL

Background

 

A VC++ application will fail to run if the required Visual C++ runtime libraries are not present on the target operating system (machine). It’s the manifest of the executable used by the operating system loader to load assemblies that your application depends on. Any C/C++ program built by Visual C++ 2005/2008 has to include a manifest describing its dependencies on Visual C++ libraries.

If the loader fails to resolve the correct assemblies the applications either fails at the start or might crash later. Manifest can either be embedded inside the binary as a resource, or saved as an external file in the application's local folder. To deploy VC++ runtime libraries with the executable there are some ways described in these links . The xCopy deployment of VC++ runtime libraries works, when a target machine doesn’t have the required VC++ runtime in the WinSxS folder.

Briefly, “app config file” is an XML configuration file that redirects a specific application (or modules which have their own manifest) from using one version of a side-by-side assembly to another version of the same assembly. “App Config file” has an element bindingRedirect which does the redirection it has the name and versions of the assembly to be redirected. For more on “App Config files” their pro and cons please visit the link.

The Problem

You would create an app config file for executable if its manifest shows dependency on a version V1 for a VC++ runtime assembly; however there is a higher version V2 of the same assembly available in the application folder, so you would like your application to load the higher version V2 and config file does that.

At runtime the operating system loader reads the config file present for the exe and loads the V.2 assembly as mentioned in the bindingRedirect element.

Also note, if the V.2 version of the same assembly is present in the WinSxS folder, the application would not require the “app config file”, it’s the “Policy File” present in the WinSxS folder for VC++ runtime libraries which did this binding redirection automatically.

Now comes the highlight of this write-up. Similar to the executables, Dlls may also have their own configuration files for the binding redirection, see below how.

Imagine you have an executable which uses a 3rd party VC++ DLL (built with msvcr80.dll version 8.0.50727.42) and the exe is being built with version 8.0.50727.762. This can be seen in the manifest information of exe and dll.

If you run this application on a machine where 8.0.50727.762 version of msvcr80.dll is present in the WinSxS folder it will run just fine, application will load 8.0.50727.762 of msvcr80 or a higher version if that present. The Policy file does this auto redirection for exe and dll both, as long as WinSxS has 8.0.50727.762 version.

Also on the development machine this application would run but on a machine where you Xcopy the 8.0.50727.762 version of msvcr80.dll in the executable’s directory it will fail to start with a side by side error, as the loader will not be able to find 8.0.50727.42 version of msvcr80.dll for the dll.

The second problem which can happen is –

Suppose you have a VC++ 2005 built application and you also have the latest ATL security patch updates (8.050727.4053) on your build machine. This same application depends on a third party dll which is built with the SP1 version (8.050727.762) of VC++ runtime. On the development machine everything works.

But also imagine on the target machines you don’t have the latest security patch dlls (8.050727.4053) in the WinSxS folder, but you have 8.050727.762 version of runtime present there.

So XCopy(application local deployment) strategy to distribute the newer runtime (8.050727.4053) will strike and you deploy the 8.050727.4053 version in the application folder. Since the third party libraries depends on the 8.050727.762 version of CRT you thought of supplying an application configuration for the Executable doing the redirection of VC runtime to 8.050727.4053 for the dll.

Now the application will start on this machine but if you see in Procmon you will see two different version of CRT library, versions 8.050727.4053 and 8.050727.762 loaded in the process space, which will lead to application crash in some scenario.

Why didn’t the config file work in the second scenario? It’s WinSxS folder which takes the precedence over the app local directory while loader searches for VC++ runtime. That’s the reason the loader finds the .762 version in the WinSxS folder and .4053 in the local folder.

The Workaround:

In both the above two scenarios you can have a “Configuration File” for your dll for the redirection from 8.0.50727.762 to 8.050727.4053. Add a configuration file for the exe and also add the configuration for you 3rd party Dll. A “foo.dll” will have its configuration file named as “foo.dll.2.config”

In this link under “File Name Syntax” the syntax “example.exe.<resource ID>.config “ is given it works for executables , a similar syntax works for the dlls as well.

 

-Bhupendra Dhyani