How I can I link dll library to my application? [duplicate] - c++

On linux, we have LIBRARY_PATH and LD_LIBRARY_PATH environment variables in order for programs to search for libraries. Do we have similar thing on windows? Particularly Windows 7?
Also, I would like to know best practices for DLL use (where to put them, use envs or not, etc.), since I want to work on windows like everyone does, and not to sloth myself on workarounds :)

Edit: As explained by Bob, this answer describes the Alternate Search Order, which is not what most applications would see. The full rules are quite complex. I don't think I can summarize them here. Instead, read the Microsoft docs - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
My original answer was:
This MSDN article explains the default search order. I quote:
The directory specified by lpFileName.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
In (1), if you statically linked against the DLL's stub library, I think "the directory specified by lpFileName" is the process's exe's path.

Take a look at the help for the LoadLibrary and CreateProcess functions. These describe the paths used to locate DLLs, and how you can modify them.

It looks on currentDir first then WinDir and SystemDir also in your path

According to what #andrew has mentioned in his answer, the order of folders that are used on Windows to search a DLL may be different from one configuration to another. I think the simplest way to check this order on Windows is to use the Dependency Walker tool. After opening the tool, and pressing the "Configure Module Search Order" button on the toolbar, you will see a window like this:
This window shows you the current search order on your machine. The interesting part is that by pressing "Expand", you can see the whole folders in the search path one by one. You may also change the order if you want, to be used for loading an specific module.

Related

How can I control search order for DLLs to avoid hijacking?

As a background: my application requires:
admin privileges
access to WinAPI DLLs
be able to run on all OSs: Win7-Win10
Normally, to use API, I can just link required *.lib files. However it uses default search order, that means (according to https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order) it firstly loads DLLs from "The directory from which the application loaded."
As a result, if the DLL exists in the same directory, running my app by double-click loads also that DLL.
I want to look for DLLs only in system directories (similarly to https://stackoverflow.com/a/46182665/9015013 ).
I know I can try to create some kind of proxy, like
BOOL WinAPIFunction(WinAPIType param) {
return reinterpret_cast<decltype(&WinAPIFunction)>(
reinterpret_cast<void*>(GetProcAddress(manually_loaded_module, "WinAPIFunction")))(param);
}
But it is hard to maintain all these functions. Is there any better method to force windows to look only in system32? I thought about manifest file but it requires version for each DLL that can break "capability" requirement (DLLs have different version for Win7 and Win10)
The solution is posted by #Eryk Sun in comment above.
It is sufficient to add all DLLs not listed in known dlls to delayed loaded libraries and call SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); at the beginning of the WinMain.
Thanks
You can try to use "Known DLLs" feature: If Windows "knows" that DLL, Windows doesn't search dll file. Known feature is described into link, you written in question.

Load a DLL from another directory at program start

My basic issue is this: my program (MyProgram.exe) has a dependency on a DLL from another program (OtherProgram), and I'm trying to avoid repackaging a new DLL every time OtherProgram updates. I'd like to have MyProgram.exe link in OtherProgram's DLL when it launches, but I'm not completely sure that Windows allows for this. So if there is some kind of workaround that would also be acceptable.
And just for some background, the platform is Windows 7 x64, and MyProgram.exe runs fine when I create a symlink in the MyProgram.exe project directory to the DLL in OtherProgram's install directory. When I try to run it without the symlink, I get the "program can't start because OtherProgramDLL.dll is missing from your computer" error.
Any advice or links to relevant info is greatly appreciated!
EDIT: Clarification: the DLL is not linked at compile-time, this issue crops up at runtime
There are two types of dynamic linking in the Windows world:
Load-Time linking is when a DLL is loaded automatically when your program starts up. Windows finds this DLL using a specific algorithm I'll discuss below.
Run-Time linking is when you specifically load a DLL by calling LoadLibrary in your code. Similar rules apply as to how the library is found, but you can specify a fully-qualified or relatively-qualified path to control the search.
In the case of Load-Time linking, MS recommends that your program's DLLs are stored in and loaded from the same directory where your application is loaded from. If this is at all workable, this is probably your best option.
If that doesn't work, there are several other options, outlined here. One is to leverage the search order by putting the DLL in either the working directory or the directory where the application was loaded from.
You can change the working directory of an application by:
Create a shortcut to your application.
Bring up the shortcut's properties
Edit the "Start in" property with the directory where the DLL is located.
When you launch your application using the shortcut, it will load the right DLL.
Other options for load-time linking include:
Adding a manifest to your application which specifies where your dependent assemblies are, or,
Setting the PATH.
You could use LoadLibrary, but you would need a way to guarantee the DLL's location. This Wikipedia article provides good example on how to use the DLL after it has been loaded.
You can add the directory where the dll is located to the PATH environment variable.
I have struggled with the same problem and also found a dead end with the suggested methods like LoadLibrary, SetDllDirectory, Qt's addLibraryPath and others. Regardless of what I tried, the problem still remained that the application checked the libraries (and didn't find them) before actually running the code, so any code solution was bound to fail.
I almost got desperate, but then discovered an extremely easy approach which might also be helpful in cases like yours: Use a batch file! (or a similar loader before the actual application)
A Windows batch file for such a purpose could look like this:
#echo off
PATH=%PATH%;<PATH_TO_YOUR_LIB>
<PATH_TO_YOUR_APP_EXE>
/edit: Just saw #SirDarius comment in Luchian's answer which describes that way, so just take my batch code bit as a reference and all credits go to him.
I have the same problem with one application I am working on.
I do not want to use runtime loading because there are tens of functions I would need to manually create function pointer for.
Mr Dibling's mention of manifest file opened a new door for me but I sadly found out that the oldest version of windows that supports the feature is Windows 7. It won't even work on Vista.
Long story short, a friend familiar with Windows Application development told me to look up Delay-Loaded DLL, which turns out to solve the problem perfectly with minimal effort. It delays the loading of DLL library to either the point you manually do, or the first time its function is called. So you just need to add your DLL path to the search path before that happens, where SetDllDirectory helps.
Here is the steps to make it work:
1) Specify the DLL to be delay-loaded to linker, either through your makefile, cmake or VS property page (Linker->Input of VS2015)
2) Call SetDllDirectory at the beginning of your program, before any call to the DLL is made.
Delay-loaded DLL is supported all the way back to VC6.
SetDllDirectory is supported after XP SP1.
Use Symbolic Links to the 3rd Party Executables
I found the approach advocated by Aaron Margosis useful. See:
Using NTFS Junctions to Fix Application Compatibility Issues on 64-bit Editions of Windows
Essentially, create symbolic links to each of the dependent 3rd Party executables. Place these symbolic link files in and amongst your own dependent executable files. Except for filename changes to the targets, the 'soft' symbolic links will resolve the load-time dependencies even as the target of the links are changed by future updates.

Get a directory path with console-like behaviour

I am developing a non-GUI application for Linux. At some point I ask the user to input a directory path, which will be used to store files.
It there a way to have behaviour similar to the console (eg. when pressing TAB, the path is automatically filled for you, or available directory paths are printed)?
What is the usual solution for this kind of problem, in case what I am looking for doesn't exist?
The usual solution is to use readline's completion facility, just like the shell does.
What you are looking for is the readline library

How can I make a separate folder for my application's DLLs?

I have successfully divided a large MFC project into a couple of smaller DLL projects. Now I want to have a separate folder called "DLL" in my application's folder, where all the all the DLLs from the subprojects are placed.
Can anybody give me guidance in how to achieve this?
If you use LoadLibrary, you simply have to explicitly specify the full path of the DLLs you load.
If the DLLs are implicitly linked, you can do this in two ways.
Have the installer modify the PATH variable. This is intrusive and "bad form"
Write a "loader" application that locally modifies the path variable, then executes the real executable.
The best solution would be to simply put the DLLs in the same directory as the executable.
DLL redirection is a fairly new feature (Windows 2000 IIRC). Name your DLL directory <myapp>.exe.local, and Windows will check it first for anything loaded via LoadLibrary(Ex). This includes delay-loaded DLLs.
EDIT: As pointed out by Eric this doesn't work. Sorry.
See Dynamic-Link Library Search Order. In short you can do so using registry keys under the "HKEY_LOCAL_MACHINE\SORTWARE\Microsoft\Windows\CurrentVersion\App Paths" key.
A reg file like the following shows how:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\MyApp.exe]
#="C:\\Program Files\\MyCompany\\MyApp\\MyApp.exe"
"Path"="C:\\Program Files\\MyCompany\\MyApp\\MyDLLs"

How would I inform an isolated application of the location of dependent DLLs?

I have a couple of isolated applications that I am writing that all rely on dlls that are also written by myself and team. Things were fine when we only had a few dlls but not the build output directory is getting rather cluttered and hard to navigate. I would ultimately like to have the output build directory contain the following structure:
$(OutDir)
--(Application.exe)
--(Application.exe)
--Libs Folder
--(LibA.dll)
--(LibB.dll)
(etc)
Is there a way to have the applications look in the "Libs Folder" for these libraries at runtime using something like the manifest files?
Dynamic-Link Library Search Order describes what possibiites you have to modify the search path. It describes the search order and mentions manifests and the SetDllDirectory() function as possibilities of changing the search order.
While SetDllDirectory looks promising, it only will reliably work if you dynamically load your DLLs, which you don't do from what I understand.
Now, as to using manifests: Application Configuration Files talks about a privatePath attribute that can be used to [specify] the relative paths of subdirectories of the application's base directory that might contain assemblies. It sound to me as if it's only supposed to work for side-by-side assemblies but you may want to give it a try.
I will readily admit I have never bothered with manifests (except for what you need to know in VS 2005 to get anything running at all) and I would recommend to skip the idea of the library subdirectories for implicitly loaded DLLs and put them in the app directory and be done with it. For explicitly (dynamically) loaded DLLs, you can just deduce their full path from your executable path and supply that to LoadLibrary() and don't need to bother with the search path either.