Delphi LoadLibrary Failing to find DLL other direc

2019-07-23 12:14发布

问题:

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:

  1. Modify the windows path, probably in the installer. That's ugly.
  2. Add a second copy of the DLL, directly into the unwantedstepchild folder. Also ugly
  3. Delay the project while we code and test a proper fix. Unacceptable.
  4. Other?

Thanks for any guidance, especially with "Other". I understand that this issue is not necessarily specific to Delphi. Thanks!

回答1:

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.



回答2:

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 via SetDllDirectory.

From MSDN-Doku:

The search path can be altered using the SetDllDirectory function. This solution is recommended instead of using SetCurrentDirectory or hard-coding the full path to the DLL.

You would have needed to add one line before your LoadLibrary call(s):

SetDllDirectory(PChar('c:\fooapp'));


回答3:

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.