54

On Linux/GCC I can use the -rpath flag to change an executables search path for shared libraries without tempering with environment variables.

Can this also be accomplished on Windows? As far as I know, dlls are always searched in the executable's directory and in PATH.

My scenario: I would like to put shared libraries into locations according to their properties (32/64bit/Debug/Release) without taking care of unique names. On Linux, this is easily be done via rpath, but I haven't found any way doing this on Windows yet.

Thanks for any hints!

Sridhar Ratnakumar
  • 81,433
  • 63
  • 146
  • 187
  • A nice trick by binary patching: https://nibblestew.blogspot.com/2019/05/emulating-rpath-on-windows-via-binary.html (Web Archive - https://web.archive.org/web/20230120211333/https://nibblestew.blogspot.com/2019/05/emulating-rpath-on-windows-via-binary.html). – Royi Jan 20 '23 at 21:14
  • Also on http://blog.omega-prime.co.uk/2012/12/06/rpath-emulation-absolute-dll-references-on-windows/. – Royi Jan 20 '23 at 21:18
  • Related docs: [Dynamic-link library search order](https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#standard-search-order-for-unpackaged-apps) – starball Feb 22 '23 at 21:27

3 Answers3

29

Sadly there is no direct analogue to RPATH. There are a number of alternative possibilities, each of them most likely undesirable to you in its own special way.

Given that you need a different exe for each build flavor anyway to avoid runtime library clashes, as you might guess the easiest thing to do is to put each exe in the same folder as each set of DLLs.

As you also mentioned, the most universal method is to change the PATH variable by using a batch file to bootstrap the exe.

You could instead change the current working directory before running the program to the desired DLL folder.

You can use the function SetDllDirectory or AddDllDirectory inside your exe. This is probably the closest to an RPATH, but only works on WinXP SP1 or later.

If you're willing to alter the file name of each exe flavor, you can use the "App Paths" registry key. Each exe would need a unique filename.

Christian
  • 1,017
  • 3
  • 14
  • 30
kbluck
  • 11,530
  • 4
  • 25
  • 25
  • Unfortunately, Microsoft closed the trick of writing a modified system ᴅʟʟ inside directory from which the application loaded for hacking (since it allowed to override system ᴅʟʟ in System32) with recent Windows 10 builds. This means ᴅʟʟs inside directory from which the executable start can no longer be loaded. – user2284570 Dec 26 '18 at 13:59
  • 1
    Actually this was hardly ever a trick. Well-known DLLs are pre-loaded at system start (i.e. Section/MMF objects exist for them). These will _always_ preferred over the ones located _somewhere_. But there are still ways to tinker with all of this through TLS callbacks and delay-loading. – 0xC0000022L Sep 20 '21 at 13:02
  • ... and yes, with some creative thinking delay-loading can also be used with well-known DLLs – 0xC0000022L Sep 20 '21 at 13:36
8

The search order for DLLs in Windows is described on this page on MSDN. If you're using run-time dynamic linking, you can specify the folder when you call LoadLibrary.

ChrisN
  • 16,635
  • 9
  • 57
  • 81
7

"Isolated applications" is a mechanism for embedding an XML manifest that describes the DLL dependencies.

Adam Mitz
  • 6,025
  • 1
  • 29
  • 28
  • This mechanism is only meant for assemblies. This belongs to managed code. – Christian Apr 10 '12 at 12:35
  • 1
    Do you have a reference for that? Everything I've seen around this topic seems to allow native code DLLs just the same. – Adam Mitz Apr 10 '12 at 16:43
  • Assembly is defined on [Wikipedia](https://en.wikipedia.org/wiki/.NET_assembly). MSDN seems to use the term Assembly only in conjunction with the MSI [Assemblies](http://msdn.microsoft.com/en-us/library/aa367757%28v=vs.85%29.aspx). So your referenced article is belonging to an installed application. The rpath information is embedded into the application and does not relay on an installation. Rpath is effective just after linking. – Christian Apr 11 '12 at 12:36
  • This doesn't match anything I've seen. Wikipedia isn't the authority on how Windows APIs work, MSDN is. I will leave the answer alone, feel free to post your own. – Adam Mitz Apr 12 '12 at 01:13
  • @AdamMitz could you give an example? I don't see the way to specify that specific DLL shall be loaded from a specific folder after reading MSDN on Application manifests. – mlt Jun 06 '12 at 01:14
  • 4
    @Christian: Your Wiki definition is for a .NET assembly, which is managed only, of course. But an assembly is not necessarily a .NET assembly. An assembly on Windows is effectively little more than a pairing of an executable image and an XML file describing it, and it most certainly applies to non-managed code as well. :) – jalf Apr 25 '13 at 11:35