Delphi LoadLibrary 无法找到 DLL 其他目录 - 有什么好的选择吗?
两个 Delphi 程序需要加载 foo.dll,其中包含一些将客户端身份验证证书注入 SOAP 请求的代码。 foo.dll 驻留在 c:\fooapp\foo.dll 中,通常由 c:\fooapp\foo.exe 加载。效果很好。另一个程序需要相同的功能,但它驻留在 c:\program files\unwantedstepchild\sadapp.exe 中。两个 aps 都使用以下代码加载 DLL:
FOOLib := LoadLibrary('foo.dll');
...
If FOOLib <> 0 then
begin
FOOProc := GetProcAddress(FOOLib , 'xInjectCert');
FOOProc(myHttpRequest, Data, CertName);
end;
它对于 foo.exe 非常有用,因为 dll 就在那里。 Sadapp.exe 无法加载库,因此 FOOLib 为 0,其余部分永远不会被调用。因此,sadapp.exe 程序无法注入证书,并且当我们对生产进行测试时,如果证书丢失,连接是否会失败。显然,我们应该完全限定 DLL 的路径。在不涉及很多细节的情况下,直到最近,测试的某些方面都掩盖了这个问题,现在在代码中修复基本上为时已晚,因为这需要完整的回归测试,而且没有时间这样做。
既然我们已经把自己逼到了墙角,我需要知道是否有任何我忽略的选择。虽然我们无法更改代码(对于此版本),但我们可以调整安装程序。我发现将 c:\fooapp 放入路径中是可行的。与将 foo.dll 的第二个副本直接添加到 c:\program files\unwantedstepchild 中一样。 当sadapp.exe运行时,c:\fooapp\foo.exe将始终运行,所以我希望Windows能以这种方式找到它,但显然不是。有没有办法告诉 Windows 我确实想要同一个 DLL?也许是清单之类的?这就是我正在寻找的那种“灵丹妙药”。 我知道我可以:
- 修改 Windows 路径,可能在安装程序中。那太丑了。
- 将 DLL 的第二个副本直接添加到 unknownstepchild 文件夹中。 当我们编码和测试正确的修复时,也很丑陋
- 延迟项目。不可接受的。
- 其他?
感谢您的任何指导,特别是“其他”。据我了解,这个问题不一定是 Delphi 特有的。谢谢!
Two Delphi programs need to load foo.dll, which contains some code that injects a client-auth certificate into a SOAP request. foo.dll resides in c:\fooapp\foo.dll and is normally loaded by c:\fooapp\foo.exe. That works fine. The other program needs the same functionality, but it resides in c:\program files\unwantedstepchild\sadapp.exe. Both aps load the DLL with this code:
FOOLib := LoadLibrary('foo.dll');
...
If FOOLib <> 0 then
begin
FOOProc := GetProcAddress(FOOLib , 'xInjectCert');
FOOProc(myHttpRequest, Data, CertName);
end;
It works great for foo.exe, as the dll is right there. sadapp.exe fails to load the library, so FOOLib is 0, and the rest never gets called. The sadapp.exe program therefore silently fails to inject the cert, and when we test against production, it the cert is missing, do the connection fails. Obviously, we should have fully-qualified the path to the DLL. Without going into a lot of details, there were aspects of the testing that masked this problem until recently, and now it's basically too late to fix in code, as that would require a full regression test, and there isn't time for that.
Since we've painted ourselves into a corner, I need to know if there are any options that I've overlooked. While we can't change the code (for this release), we CAN tweak the installer. I've found that placing c:\fooapp into the path works. As does adding a second copy of foo.dll directly into c:\program files\unwantedstepchild.
c:\fooapp\foo.exe will always be running while sadapp.exe is running, so I was hoping that Windows would find it that way, but apparently not. Is there a way to tell Windows that I really want that same DLL? Maybe a manifest or something? This is the sort of "magic bullet" that I'm looking for.
I know I can:
- Modify the windows path, probably in the installer. That's ugly.
- Add a second copy of the DLL, directly into the unwantedstepchild folder. Also ugly
- Delay the project while we code and test a proper fix. Unacceptable.
- Other?
Thanks for any guidance, especially with "Other". I understand that this issue is not necessarily specific to Delphi. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
LoadLibrary 的 MSDN 文档告诉您 Windows 的确切位置将搜索 DLL。您要么必须对 DLL 的路径进行硬编码,将其放在与应用程序相同的文件夹中,要么将其放在 LoadLibrary 文档中的默认搜索位置之一。
The MSDN documentation for LoadLibrary tells you exactly where Windows will search for the DLLs. You either have to hard-code the path to the DLL, put it in the same folder as your app, or put it in one of those default search locations from the LoadLibrary docs.
这并不完全是所问问题的解决方案,但当我偶然发现这个问题时,它会对我有所帮助:
您可以通过
SetDllDirectory
。来自 MSDN-Doku:
您需要在
LoadLibrary
调用之前添加一行:This is not exactly a solution for the question asked, but it would have helped me, when I stumpled upon this question:
You can extend the search path for
LoadLibrary
viaSetDllDirectory
.From MSDN-Doku:
You would have needed to add one line before your
LoadLibrary
call(s):或者您可以简单地编辑环境变量“path”并将 dll 的路径放入其中。在这种情况下,将
;c:\fooapp
添加到路径就足够了。由于父级的环境更改会影响子级,因此您还可以创建一个加载器应用程序来调整其环境变量,然后生成您的应用程序。Or you can simply edit the environment variable "path" and place the path to the dll in there. In this case adding
;c:\fooapp
to the path should be sufficient. Since the environment changes of a parent effects a child, you can also create a loader application which adjusts the its environment variable then spawns to your application.