Wednesday, 19 November 2008

A letter from DLL hell: msvc60.dll and msvcr80.dll

This is only a short technical note - for those who (like me) first check the Internet for solution to weird programming questions!

The Problem:

Locally everything worked fine: I could install my old (VC++ 6.0) Windows application and start it without a hitch. But at client's site (1000s of miles away) Windows refused to start as it couldn't find the msvcr80.dll library.

What the heck, I link against msvc60.dll but Windows complains about msvcr80.dll which I don't use, don't link, and don't need??? I that black magic? Help!!! That was the problem I was fighting for the best part of one of last weeks. Welcome in the manifest/DLL hell. Well, I tried first to reproduce this locally: it didn't work (i.e. it did work ;-))) on my develpoment Widows XP machine, as well as a freshly installed Windows Server 2003 Std. Edition (SP2), a running Windows Server 2003 Web Edition (SP1), and it always worked! No probs at all when starting the app!

At the client there was the Windows Server 2003 Web Edition (SP2), with "nothing installed" (as asserted by my colleague at the client' s site) except for our product and Oracle! What's going on? There are no dependencies to msvcr80.dll in my code (I checked with the Dependency Walker) and the installation worked for years before I made that last bugfix!

In the last attempt to reproduce the error I found a running installation of Windows Server 2003 Web Edition (SP2) at my client's company local site and could at last see it with my own eyes: "Cannot start application, msvcr80.dll not found".

The Solution:

It's elementary: if there's no static dependency, ther must be a dynamic one! The Process Explorer has shown, that the process has really tried to load the msvcr80.dll! How? Through the Qt plugin mechanism:

"Qt applications automatically know which plugins are available, because plugins are stored in the standard plugin subdirectories. Because of this applications don't require any code to find and load plugins, since Qt handles them automatically.

The default directory for plugins is QTDIR/plugins*, with each type of plugin in a subdirectory for that type, e.g. styles..."

Although I used the Qt version 3, this generic mechanism pulled in all the plugins found, which were OK, except for the styles plugin qtdotnet2.dll. Because of course "nothing else installed" wasn't true: the Base package of my client was there, and it had various plugins installed, including the culprit: qtdotnet2.dll, which was written for Qt version 4 and pulled in the Visual C++ 2005 runtime support!


No comments: