LoadLibraryEx 标志似乎什么也没做

问题描述 投票:0回答:1

我目前正在编写一个加载 DLL (

a.dll
) 的程序,该程序依赖于另一个 DLL (
b.dll
)。

使用

LoadLibrary
功能时,加载
a.dll
成功;只要
b.dll
与可执行文件位于同一目录中(无论
a.dll
位于何处)。但是,就我的目的而言,
b.dll
不能与可执行文件位于同一目录中。因此,我求助于
LoadLibraryEx
,它有一个 flags 参数,可以在加载 DLL 时提供更具体的参数。然而,他们似乎都没有做任何事情。无论我过去几个小时尝试了什么,所有对
LoadLibraryEx
的调用都会失败并返回错误代码
126

HANDLE handle;

// this works if b.dll is in the same
// directory as the executable file
handle = LoadLibrary("a.dll");
FreeLibrary(handle);

// this also works, since using a value
// of zero for the flags makes it behave
// the same as LoadLibrary
handle = LoadLibraryEx("a.dll", NULL, 0);
FreeLibrary(handle);

// this does not work, even if b.dll is
// in the same directory as the executable
// file
handle = LoadLibraryEx("a.dll", NULL,
    LOAD_LIBRARY_SEARCH_APPLICATION_DIR);

// this does not work, even if b.dll is
// in the same directory as a.dll
handle = LoadLibraryEx("a.dll", NULL,
    LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);

// this does not work, even if b.dll is
// in one of the directores specified by
// a sucessful call to AddDllDirectory
DLL_DIRECTORY_COOKIE cookie =
    AddDllDirectory(L"C:\\Fully\\Qualified\\Path");
handle = LoadLibraryEx("a.dll", NULL,
    LOAD_LIBRARY_SEARCH_USER_DIRS);
RemoveDllDirectory(cookie);

注意:如果您需要更多信息,请在评论中告诉我,我将很乐意提供。此外,如果您选择否决这个问题,请在评论中告诉我原因。

c++ c winapi dll
1个回答
0
投票

LoadLibraryEx

 定位 DLL 的方式也适用于正在加载的 DLL,而不仅仅是其依赖项(事后看来,这对我来说应该是显而易见的,但这就是凌晨 1:30 之前编程的地方)。例如,如果我们有以下文件结构:

C:/ ├─ Program Files/ │ ├─ My Program/ │ │ ├─ addons/ │ │ │ ├─ a.dll │ │ ├─ depend/ │ │ │ ├─ b.dll │ │ ├─ program.exe
并且 

program.exe

 运行以下命令:

DLL_DIRECTORY_COOKIE cookie = AddDllDirectory(L"C:\\Program Files\\My Program\\depend"); HANDLE handle = LoadLibraryEx("addons\\a.dll", NULL, LOAD_LIBRARY_SEARCH_USER_DIRS);
Windows 将尝试在 

a.dll

 打开 
C:\\Program Files\\My Program\\depend\\addons\\a.dll
,但会失败,因为该文件不存在。在这种情况下,可以通过以下两种方法之一来解决。

    使用绝对路径而不是相对路径。
// Since an absolute path is used, Windows does not need to search // for a.dll (and thus, successfully opens it). Afterwards, it will // search for, and successfully find, b.dll in the previously given // depend folder. DLL_DIRECTORY_COOKIE cookie = AddDllDirectory(L"C:\\Program Files\\My Program\\depend"); HANDLE handle = LoadLibraryEx("C:\\Program Files\\My Program\\addons\\a.dll", NULL, LOAD_LIBRARY_SEARCH_USER_DIRS); FreeLibrary(handle); RemoveDllDirectory(cookie);

    或者,通过添加额外的 DLL 目录(在本例中为
  1. C:\\Program Files\\My Program
    )。
// Here, since the program folder has also been added as a // directory to search through, a.dll will be successfully // found in the addons folder. DLL_DIRECTORY_COOKIE programCookie = AddDllDirectory(L"C:\\Program Files\\My Program\\"); DLL_DIRECTORY_COOKIE dependCookie = AddDllDirectory(L"C:\\Program Files\\My Program\\depend"); HANDLE handle = LoadLibraryEx("addons\\a.dll", NULL, LOAD_LIBRARY_SEARCH_USER_DIRS); FreeLibrary(handle); RemoveDllDirectory(programCookie); RemoveDllDirectory(dependCookie);
此外,

确保在提供L"path"

的路径时使用宽字符串(例如,
AddDllDirectory
)!
当我不使用它们时,
LoadLibraryEx
有时会在错误的文件夹中查找。例如,
C:\\Fully\\Qualified\\Path
 会变成类似 
C:\\Fully\\重武器家伙\\Path
 的东西——至少根据 Process Monitor 是这样的。在这一点上,
确保您始终对您调用的任何函数使用正确的字符串编码。


特别感谢

@273K 在评论中向我提及 SysInternals Process Monitor。它和 Microsoft 的Dynamic-Link Library Security 文章都有助于解决此问题。

© www.soinside.com 2019 - 2024. All rights reserved.