5

I've run into a situation where an application has multiple (incompatible) versions of one or more dll.

app.exe
a.dll                // v3.0
...
plugins/foo/foo.dll
plugins/foo/a.dll    // v4.0
plugins/foo/...

In this example, app.exe depends on a.dll v3.0 and foo.dll depends on a.dll v4.0. Due to the search order of LoadLibrary the a.dll v3.0 next to my exe is loaded first, then since it's already in memory, the later v4.0 is skipped.

Assuming I cannot:

  • rename the dependent dll (a.dll in this case)
  • modify app.exe nor foo.dll to upgrade/downgrade them to a common a.dll version

Is there a way to load multiple versions of the same-named dll to work around this? I saw this answer regarding AppDomain but that is for managed C# applications, my use case is a native C++ dll.

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • 1
    Including the version number in the DLL name is of course indicated here, ask the owner for assistance. Failing that, you'll have to wrangle [an assembly manifest](https://learn.microsoft.com/en-us/windows/win32/sbscs/assembly-manifests). – Hans Passant Dec 18 '20 at 15:36
  • Thanks @HansPassant searching around there has now led me down the rabbit hole of [Isolated Applications and Side-by-side Assemblies](https://learn.microsoft.com/en-us/windows/win32/sbscs/isolated-applications-and-side-by-side-assemblies-portal), which at a glance sound promising. I'll do some digging and see if that can solve this use case. – Cory Kramer Dec 18 '20 at 15:55
  • 1
    Yet another rabbit hole are delayed-loaded libraries and notification hooks ([example](http://otb.manusoft.com/2013/01/using-delayload-to-specify-dependent-dll-path.htm)). But must be able to modify something. – Dialecticus Dec 18 '20 at 17:09

1 Answers1

5

What you are looking for is an Activation Context:

Activation contexts are data structures in memory containing information that the system can use to redirect an application to load a particular DLL version, COM object instance, or custom window version. One section of the activation context may contain DLL redirection information which is used by the DLL loader; another section may contain COM server information. The activation context functions use, create, activate, and deactivate activation contexts. The activation functions can redirect the binding of an application to version-named objects that specify particular DLL versions, window classes, COM servers, type libraries, and interfaces. For more information about the activation context functions and structures, see the Activation Context Reference.

app.exe can use one Activation Context while loading a.dll v3.0, and use another Activation Context while loading foo.dll so it uses a.dll v4.0 instead.

Raymond Chen posted a blog article, How can I specify that my DLL should resolve a DLL dependency from the same directory that the DLL is in?, which covers a scenario very similar to yours:

A customer had a program that loaded two DLLs, let’s call them A.DLL and B.DLL. Both of those DLLs use a common helper DLL called C.DLL. The catch is that the two DLLs want to use different incompatible versions of C.DLL. The two DLLs A.DLL and B.DLL reside in separate folders, and each folder has a corresponding copy of C.DLL.

Except that his solution uses a manifest-based approach to make the Activation Context of B.DLL implicitly handled by the system. If you can modify foo.dll to include a manifest, you can take a similar approach in your situation. Otherwise, you would have to make app.exe create a new Activation Context manually before loading foo.dll.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770