强制 Qt5 从 exe 目录加载 SSL dll
Force Qt5 to load SSL dlls from exe dir
更新 对不起各位,我是错误判断的问题。一切正常,错误在 "other program logic"。请删除或关闭问题。
Qt5 旨在在程序启动时加载 libeay32.dll
和 ssleay32.dll
,然后再执行 main()
中的任何指令(因为它是静态的)。
(详情: 位于qtbase\src\network\ssl\qsslsocket_openssl_symbols.cpp
:
static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
)
问题:
- 我的程序不是以其 exe 目录作为工作目录启动的
libeay32.dll
和 ssleay32.dll
驻留在其 exe 目录中
- 用户无法在系统目录中安装 OpenSSL
- 用户不能更改 PATH 变量
- 我无法重新编译 Qt,即使用 openssl-linked 编译的静态 Qt 发布程序
Qt 按以下顺序加载搜索 dll(从 qtbase\src\corelib\plugin\qsystemlibrary.cpp
):
- 应用程序路径。
- 系统库路径。
- 正在尝试 PATH 环境变量中的所有路径。
没有。 1是应用程序路径,但实际上并没有在那里搜索。
我的程序:
int main()
{
// at this point Qt5 already checked and tried to load the DLLs
// so this:
ChangeCurrentWorkingDirectoryToExeDir(); // some function to change cwd to current exe dir
// does not work :-(
// ... other program logic ..
}
如何在更改工作目录后强制Qt5 重新加载OpenSSL DLL?
可能有人已经遇到过这个问题...
更新 对不起各位,我是错误判断的问题。一切正常,错误在 "other program logic"。请删除或关闭问题。
QSystemLibrary::load
与 onlySystemDirectory = false
一起为 SSL 调用,因此 QFileInfo(qAppFileName()).path()
是搜索 DLL 的第一个位置。搜索顺序:
- 应用程序目录
- 系统路径(例如 C:\Windows\System32)
- PATH 中的所有路径
我找不到这方面的文档,但在我们的软件中,Qt 发现 SSL libeay32.dll
和 ssleay32.dll
当它们与应用程序 .exe 位于同一目录时,鉴于
- .dll 文件不在路径中
- .dll 文件不在工作目录中
- 不存在qt.conf
如果您有 qt.conf
,则可能会应用默认库值,即 .\lib
。
MSDN 上的 Dynamic-Link Library Search Order 讨论了库搜索顺序。
有几种方法可以处理加载库,但听起来大多数都不适用。
我不清楚为什么可以调用ChangeCurrentWorkingDirectoryToExeDir
,但不能调用SetDllDirectory
。我可能遗漏了一些明显的东西。
您最后的选择似乎是创建一个 Qt.exe.local
文件。这称为 Dynamic-Link Library Redirection,将导致链接器加载本地文件中指定的 DLL。
更新 对不起各位,我是错误判断的问题。一切正常,错误在 "other program logic"。请删除或关闭问题。
Qt5 旨在在程序启动时加载 libeay32.dll
和 ssleay32.dll
,然后再执行 main()
中的任何指令(因为它是静态的)。
(详情: 位于qtbase\src\network\ssl\qsslsocket_openssl_symbols.cpp
:
static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
)
问题:
- 我的程序不是以其 exe 目录作为工作目录启动的
libeay32.dll
和ssleay32.dll
驻留在其 exe 目录中- 用户无法在系统目录中安装 OpenSSL
- 用户不能更改 PATH 变量
- 我无法重新编译 Qt,即使用 openssl-linked 编译的静态 Qt 发布程序
Qt 按以下顺序加载搜索 dll(从 qtbase\src\corelib\plugin\qsystemlibrary.cpp
):
- 应用程序路径。
- 系统库路径。
- 正在尝试 PATH 环境变量中的所有路径。
没有。 1是应用程序路径,但实际上并没有在那里搜索。
我的程序:
int main()
{
// at this point Qt5 already checked and tried to load the DLLs
// so this:
ChangeCurrentWorkingDirectoryToExeDir(); // some function to change cwd to current exe dir
// does not work :-(
// ... other program logic ..
}
如何在更改工作目录后强制Qt5 重新加载OpenSSL DLL? 可能有人已经遇到过这个问题...
更新 对不起各位,我是错误判断的问题。一切正常,错误在 "other program logic"。请删除或关闭问题。
QSystemLibrary::load
与 onlySystemDirectory = false
一起为 SSL 调用,因此 QFileInfo(qAppFileName()).path()
是搜索 DLL 的第一个位置。搜索顺序:
- 应用程序目录
- 系统路径(例如 C:\Windows\System32)
- PATH 中的所有路径
我找不到这方面的文档,但在我们的软件中,Qt 发现 SSL libeay32.dll
和 ssleay32.dll
当它们与应用程序 .exe 位于同一目录时,鉴于
- .dll 文件不在路径中
- .dll 文件不在工作目录中
- 不存在qt.conf
如果您有 qt.conf
,则可能会应用默认库值,即 .\lib
。
MSDN 上的 Dynamic-Link Library Search Order 讨论了库搜索顺序。
有几种方法可以处理加载库,但听起来大多数都不适用。
我不清楚为什么可以调用ChangeCurrentWorkingDirectoryToExeDir
,但不能调用SetDllDirectory
。我可能遗漏了一些明显的东西。
您最后的选择似乎是创建一个 Qt.exe.local
文件。这称为 Dynamic-Link Library Redirection,将导致链接器加载本地文件中指定的 DLL。