Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to catch the error if loading a dll cannot find a dependency?

I am writing a Windows 32 bit program that can use one of multiple possible dlls. So it tries to load each dll in turn, using SysUtils.SafeLoadLibrary and if loading succeeds, it uses that dll.

Unfortunately some of these dlls are statically linked to other dlls. These dlls may be missing from the computer. In that case I get dialog telling me

[myprogram]: [myprogram.exe] System Error

The program can't start because [some dll name] is missing from your computer. Try reinstalling the program to fix this problem."

After pressing the OK button on that dialog, the program gets the error code and tries one of the other dlls which then works fine.

Rather than showing that dialog to the user I want my program to silently ignore it.

How can I accomplish that?

In case it matters: My program is written in Delphi 2007. The Windows version is Windows 8.1, but the program should also work with other Windows versions >= Windows XP.

I have tried SetErrorMode(SEM_FAILCRITICALERRORS) but it did not make any difference.

like image 347
dummzeuch Avatar asked Oct 18 '22 11:10

dummzeuch


1 Answers

SafeLoadLibrary sets the error mode to the value that you provide as an argument, and then restores it after the call to LoadLibrary returns. Most likely you are not supplying a value for that parameter, in which case a default of SEM_NOOPENFILEERRORBOX is passed. In that case it is probably disabling SEM_FAILCRITICALERRORS which would explain the behaviour that you see.

You could solve the problem by passing SEM_FAILCRITICALERRORS every time you call SafeLoadLibrary. Or, perhaps better would be to pass the current error mode. However this is hard to obtain. In Vista and later you can call GetErrorMode. But in older versions you have to do this:

ErrorMode := SetErrorMode(0);
SetErrorMode(ErrorMode);

Because this is a process wide setting, you have a window of opportunity between the two calls to SetErrorMode, for multi-threaded applications to be caught out.

Frankly, I believe that you should call SetErrorMode exactly once in the lifetime of a process, at startup. With that in mind, I would shun SafeLoadLibrary.

If you wish to take advantage of its other function, namely to protect against changes to floating point control state, then you should implement that functionality yourself, in my opinion.

like image 52
David Heffernan Avatar answered Nov 15 '22 08:11

David Heffernan