views:

36

answers:

3

I build an executable which is dynamically linked to several DLLs. Most of these are installed by default on Windows, but maybe with slightly different versions. Others I distribute with the app, but they in turn may depend on other DLLs.

If I run the executable locally and get the Windows error message saying that "Failed to load [whatever]. The application configuration is incorrect" it seems to mean that a library that 'whatever' depends upon is missing. But it (rather infuriatingly) omits to specify exactly which DLL it was having trouble loading. Sometimes I can work this out by using Dependency Walker to see if there are any libraries that are obviously missing. Other times, I can resort to Process Monitor which can show me which file Windows was looking for prior to issuing the error message.

But these aren't tools that are reasonable for an end-user to have to use, when trying to diagnose their problem. Is there any way of coaxing Windows to say precisely which library it is having trouble resolving, so that this can be output to a log or displayed in a message box?

A: 

The windows event log usually contains some valuable information after these messages.

In XP, Right click "my computer", select "manage" and go to the "Event Viewer" there, check the system log, look for error messages which appeard about the time when the message box appeared. There should be a few of them. one of them will contain the name of the offending dll.

shoosh
I don't see anything in my event log on Vista as a result of these errors, unfortunately.
Kylotan
+1  A: 

In my experience, a common cause of this kind of error is accidentally shipping a component that was linked against the debug version of the C runtime, which is explicitly not redistributable, and so it is only on an end user's system if they happen to have the matching version of VisualStudio installed. It will have a name that looks something like MSVCR80D.DLL instead of MSVCR80.DLL.

Dependency Walker is certainly the right tool to use to check your executable as a developer. It can hook the application for DLL load events and run it, so you can discover DLLs that are dynamically loaded at run time as well as the DLLs that were named at build time.

Dependency Walker is also scriptable, and can write a log file. I use it this way as part of my build process to validate a shipment before packaging for release. I stage all the files to be shipped into a mockup of their delivered directory tree. I use a debug mode of the application hosted by dependency walker that makes it load all its optional bits and pieces then exit. Depends.exe leaves me a nice log file, which I inspect with a Perl script and fail the build if any DLL was loaded from anywhere on the system other than \WINDOWS or the staging area, or if an unexpected version or debug version of the C runtime was loaded. Only after that check succeeds do I build the InnoSetup installer package that will be released. This has saved embarrassment on a couple of occasions and was well worth the effort it took to figure out how to do.

If you know that every DLL is either an "official" Windows DLL or part of your shipment, then you have a really good chance of it all just working on the cusomer's machine.

Edit: The official home of Dependency Walker is a good place to poke around. The version offered there may be newer than the version included with MSVS, and there is a fair amount of decent documentation on advanced uses.

I can confirm that I have run IE profiled under depends.exe, but not tested much at all.

RBerteig
I didn't know about the profiling tool in Dependency Walker, so that was useful. Unfortunately I am distributing a DLL, and the host program I need to run crashes when you try and profile it in this way. The program in question is MS Internet Explorer...!
Kylotan
You can use depends on a dll, but I don't think you can profile it the same way. Could you build a simple mock up host that does the minimal amount to act enough like IE to help? I know that won't be as easy as it sounds to do... Also, Take a look a some of the options in depends. There are several that control details of that profile and what it does and doesn't do to the DLL load path.
RBerteig
One other thing... I'll edit in a link to its home page, there may be a newer version than the one you have.
RBerteig
A: 

One technique I find useful is to create an installer project in Visual Studio (even if you don't end up shipping it). Inside your solution, create a new Setup and Deployment project and add the primary output of your project to it, then build the installer. This will do a dll dependency check phase which you'll see listed in the 'Detected Dependencies' section. So if there any dlls that you have omitted you should see them in this list.

Of course, now that you have an installer that's taken only 5 minutes to set up, you could ship that and it will deal with ensuring that the Visual Studio runtimes are setup correctly too.

the_mandrill
But I already know the dependencies are fine on my machine. It's when it's been shipped out to end users that the problem arises.
Kylotan
This should pick up all the dependencies which may not be apparent because 'it just works' on your own machine. The problem is that you don't know what all the dependencies are. Dependency walker is hugely useful but one thing it doesn't tell you is: what's the list of all the dlls that aren't a core part of the OS that are needed (directly or indirectly) by my app. The fact that you're running into this problem suggests that you need an installer that will handle all this for you.
the_mandrill