添加自定义 DLL 搜索路径@应用程序启动
我正在绞尽脑汁试图想出一个优雅的解决方案来解决 DLL 加载问题。 我有一个应用程序静态链接到加载 DLL 的其他 lib 文件。 我没有直接加载 DLL。 我希望在可执行文件所在的文件夹之外的另一个文件夹中拥有一些 DLL。例如 %working_folder%\dlls - 我不想在我的 %working_folder% 中有几十个(是的...几十个)DLL 。
我正在尝试开发一些作为主应用程序一部分的东西,它将调整启动时的搜索路径。 我遇到的问题是这个新的自定义 DLL 路径不在系统搜索路径中。 当我启动应用程序时,它崩溃了(STATUS_DLL_NOT_FOUND),因为必要的 DLL 不在适当的位置。 我想做的是检查 @startup 这个新的自定义 DLL 文件夹是否在进程环境变量搜索路径中,如果没有则添加它。 问题是,应用程序在执行一行代码之前尝试加载所有这些 DLL。
我该如何解决? 我考虑过编写一个首先启动的帮助应用程序,适当调整环境变量,然后通过 CreateProcess 启动主应用程序。 我确信这会起作用,但它给开发人员带来了困难。 当他们调试主应用程序时,他们不会首先启动辅助应用程序 - 他们甚至不能这样做。
我尝试过注册表应用程序路径功能但没有成功。 和以前一样,先有鸡还是先有蛋的问题。
我在这里能做什么?
I'm racking my brain trying to come up with an elegant solution to a DLL load problem. I have an application that statically links to other lib files which load DLLs. I'm not loading the DLLs directly. I'd like to have some DLLs in another folder other than the folder that the executable is in. Something like %working_folder%\dlls - I'd rather not have dozens (yes ... dozens) of DLLs in my %working_folder%.
I'm trying to develop something that is part of the main app that will adjust the search path @ startup. The problem I'm running into is that this new custom DLL path isn't in the system search path. When I start the app it crashes (STATUS_DLL_NOT_FOUND) because the necessary DLLs are not in the appropriate places. What I'd like to do is to check @ startup if this new custom DLL folder is in the process environment variable search path and if not add it. Problem is, the application attempts to load all these DLLs before the app executes one line of code.
How do I fix this? I've considered writing a help app that starts first, adjusts the environment variables appropriately and the launches the main app via CreateProcess. This will work I'm sure of it but it makes things difficult on the developers. When they debug the main app they're not going to launch a helper app first - not that they could even do that.
I've tried the registry app path feature with no success. Same chicken and egg problem as before.
What can I do here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我发现马修的答案对我有用。
在 Visual Studio 2012 中转到您的项目属性并在
配置属性->链接器->输入->延迟加载的DLL
添加您希望在需要时才加载的每个 dll 文件。
虽然它不再需要在 main 之前运行,但这是我设置新搜索路径的代码
I found Matthew's answer worked for me.
In visual studio 2012 goto your project properties and in
Configuration Properties->Linker->Input->Delay Loaded Dlls
add each dll file that you want to not load until needed.
Although it no longer needs to run before main, this is my code to set the new search path
[编辑 - 重新阅读问题后,我发现您遇到的问题是 DLL 在
main
启动之前加载]我猜测这些库是用 C++ 编写的并且正在加载来自全局范围内某些对象的构造函数的 DLL。 这是有问题的。 请允许我引用 约西·克赖宁:
[原始答案如下]
请参阅此页面了解用于加载 DLL 的搜索算法。 您可以使用
SetDllDirectory()
将目录添加到 DLL 搜索路径。您还应该能够使用
GetEnvironmentVariable()
和SetEnvironmentVariable()
。另一种选择是使用
SetCurrentDirectory()
。 如果您使用相对文件名加载任何文件,请确保在加载 DLL 后将工作目录更改回原来的位置。[Edit - after re-reading the question I see that the problem you're having is that the DLLs are getting loaded before
main
starts]I'm guessing that those libraries are written in C++ and are loading the DLLs from the constructor of some objects in global scope. This is problematic. Allow me to quote Yossi Kreinin:
[Original answer below]
See this page for the search algorithm used for loading DLLs. You can use
SetDllDirectory()
to add a directory to the DLL search path.You also should be able to add a directory to the PATH environment variable using
GetEnvironmentVariable()
andSetEnvironmentVariable()
.Another option is to change the current working directory to the folder containing the DLLs with
SetCurrentDirectory()
. Just make sure to change the working directory back after loading the DLLs if you ever load any files using relative filenames.我的建议是对 DLL 使用延迟加载链接并尽早调用 SetDllDirectory(),以便在调用方法/函数时可以找到它们。
My recommendation is to use delayload linking for the DLLs and call SetDllDirectory() early enough so it can find them when the methods/functions are invoked.