Tim Anderson's ITWriting [Valid RSS]

Tech writing blog

Blog Home RSS Archives ITWriting.com
Add to Feedburner Add to Bloglines Add to Newsgator Add to My Yahoo

January 1, 2006

Visual Studio 2005 DLL Hell

Posted 3034 days ago on January 1, 2006

Microsoft is making strenuous efforts to eliminate DLL Hell. But is the cure worse than the disease? I'm trying to get my head round what has changed in Visual Studio 2005 with regard to unmanaged DLLs and their dependencies. I learned about this the hard way, when compiling the latest version of Sqlite and a Java JNI wrapper for Sqlite. A key factor here is that like many open source and cross-platform libraries, these are most often compiled from the command-line. I tweaked the make files, ran the latest vcvars32.bat, and got an apparently successful build. However, when I attempted to use the wrapper from Java I got an error I hadn't seen before. I have a feeling we may run across this now and again, so take a look at this:

In case you can't see the image, the message is: "The application has failed to start because MSVCR80.dll was not found. Re-installing the application may fix this problem." All a bit strange, because MSVCR80.DLL was most definitely installed; in fact a quick search revealed multiple copies on my system. However, I did the obvious thing and copied one from the Visual C++ redist folder to the application directory. Far from solving the problem, it simply changed the error to this one:

which says, "An application has made an attempt to load the C runtime library incorrectly. Please contact the application's support team for more information." Indeed. So what is going on here?

MSVCR80.DLL is the latest version of Microsoft's C runtime library. Actually there are several runtime libraries, but this is the default for DLLs compiled with the Visual Studio 2005 compiler and linker. Version mismatches in the C runtime library are a common source of application failure, so Microsoft is now enforcing the use of a manifest that identifies the exact version of the dependent file, enabling "side by side" existence of multiple versions without conflict.

That sounds fair enough, but there are many complicating factors. Not all versions of Windows support side-by-side execution, and even on those that do, the installation procedure is complex; it is more than just copying a DLL. This article does a fair job of explaining the deployment issues. However, it still wasn't clear to me why I was getting the error, especially since the compiler had generated a manifest for me. I ran vcredist_x86.exe to no avail.

I found a solution that worked for me in Richard Grimes' detailed article about unmanaged assemblies. Note that he is not polite about how all this stuff has been implemented. In essence, I had to run the mt utility as a post-build step, to embed the generated manifest into the DLL as a resource. It must be resource #2 for this to work. After that, everything was fine, though I haven't yet tried to build an installer that would be suitable for wide deployment.

I did some further tests with my simple Sqlite wrapper for Delphi, and the plain (non-JNI) version of Sqlite3.dll, and got exactly the same error.

If you compile your DLL from the Visual Studio 2005 IDE, rather than from the command-line, you will not notice this issue on your development machine. This is because the IDE will create the manifest and embed it for you. However, you still have a deployment issue. This means using a supplied merge module in a Windows Installer setup, or running vcredist_x86.exe on the target machine. The snag here is that vcredist_x86.exe (and the merge module) have their own dependencies, primarily version 3.0 of the Windows Installer runtime. Users will have this if they have Windows XP SP2. Even so, it means that installing your simple DLL or Exe might require a patch, a restart, and local admin rights.

Another option is to use static linking for the runtime library. This means using /MT rather than /MD. Note that this can change the behaviour of your code; in fact, Microsoft advises: "it is not recommended to link statically to the CRT in a DLL unless the consequences of this are specifically desired and understood." The other snag is that if a security problem is found in the runtime library, and patched, your application will not get the benefit of the patch.

The third option, of course, is to use another compiler. Some people prefer Visual C++ 6.0 because it links to the standard msvcrt.dll, which is pretty much guaranteed to be present on all 32-bit versions of Windows, though you could hit version problems (old-style DLL Hell).

I have some sympathy with Microsoft. It really is trying to solve DLL versioning issues; and some of these issues are inherently intractable. Even so, I'm not sure about the wisdom of requiring side-by-side for msvcr80.dll (and a few others). However, developers must understand these deployment issues, otherwise we'll see more error dialogs like the ones above.

...and one more thing HAPPY NEW YEAR

Update

I've noticed an excellent post and discussion by Martyn Lovell, a member of the C++ team at Microsoft who says he owns "...libraries, which means the C and C++ runtimes and standard libraries, MFC, ATL, ATL Server, and some new libraries we're creating for managed code applications". Lovell explains the rationale behind side-by-side and highlights the recommendation not to use static linking to the runtime libraries; he also observes that Visual C++ 6.0 is now unsupported. It won't be easy, but it's our call.

Update 2

If you read the discussion following Lovell's article referenced above, you'll notice that there is a documented way to install the runtime libraries without registering side-by-side assemblies:

However, if you want to install-applocal, you should make sure that your application has a manifest, and then copy the whole of this folder into your EXE directory:
X:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT
and other folders if you use more than the CRT. Make sure you include the manifest.

I tried this when I first hit this issue and it didn't work; but that was before I embedded the manifest. It sounds to me like it should work provided that you embed the manifest. In other words, you can still get xcopy deployment to a clean Windows box. Note that this is still not a recommended approach, because the libraries will not get patched by Windows Update, though there is the possibility of a tool that searches the hard drive for all instances of an insecure library.



Re: Visual Studio 2005 DLL Hell

Posted 3034 days ago by Roger Binns • • • Reply

Also don't forget the license Microsoft requires the redistributable portion to be under. It is considered to prevent redistribution with GPL software, and may have other entanglements if you are using open source components. (For example many people have problems with Python 2.4 using VC2003 as the Microsoft license is very ambiguous about who can redistribute it.)

Re: Visual Studio 2005 DLL Hell

Posted 3033 days ago by Chris Smith • • • Reply

A rather byzantine advertisement for MinGW, it seems.

The one line patch for perl salvation

Posted 2409 days ago by William A. Rowe, Jr. • • • Reply

With luck this doesn't wrap oddly... so it's really two lines if you count wrapping :)

--- lib\ExtUtils\MM_Win32.pm.save Mon Jun 18 14:52:14 2007
+++ lib\ExtUtils\MM_Win32.pm Mon Sep 17 11:00:19 2007
@@ -341,6 +341,8 @@
push(@m,
q{ $(LD) -out:$@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) }
.q{$(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)});
+ push @m, '
+ if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;2';
}
push @m, '
$(CHMOD) $(PERM_RWX) $@

This trivial patch teaches makemaker to embed manifests in all cases that they are
created as a side-effect from compiling under VC 2005. Glad to see some other fellow
soldiers still standing after the nuke that Microsoft lobbed at us :)

Re: Visual Studio 2005 DLL Hell

Posted 2932 days ago by Drew Buchett • • wwwReply

Thank you very much for posting this article. Believe it or not, when I searched for that error, this is the ONLY page that came up. I would still be banging my head against a wall trying to get apache to run if it weren't for this.

Re: Visual Studio 2005 DLL Hell

Posted 2800 days ago by Seymour Kellerman • • • Reply

I would like to run VCRedist_X86.exe from another program (using ShellExecuteEx) but in quiet mode. However, the /Q option to the VCRedist program does not work. Is there a fix for this?

Re: Visual Studio 2005 DLL Hell

Posted 2775 days ago by Peter Kidman • • • Reply

I can only install beta version of VC redistribution in my XP pro SP2 but not be able to install formal version, when trying to install formal version, it always looks for something in C: which dosen't exist. I already have newest version of Windows Installer 3.1 installed. I don't know why this happened...

Re: Visual Studio 2005 DLL Hell

Posted 2759 days ago by Avi Dunn • • • Reply

VCRedist is a MSI wrapped in a IExpress package, to make it run quiet you need to specify quiet mode from these two layers:

vcredist_x86.exe /Q:a ----> will make the IExpress package open silently

To make the MSI install quietly also you need:

vcredist_x86.exe /Q:a /c:"msiexec.exe /qn /i vcredist.msi"


Hope this helps...

Need little bit help vc++ app html is not update IE7

Posted 2455 days ago by mamoni • • • Reply

Hi all,
i need little bit help , when i update some value in form view the html view is not updated but if i save the file and open the xml file html view is display properly , means before save the html not update , but previously IE6 it was worked fine , after IE7 problem here,
please need help............

Re: Visual Studio 2005 DLL Hell

Posted 2415 days ago by Jeff Staples • • • Reply

The link to OShah's article on CodeProject site has changed. The new URL is ...
http://www.codeproject.com/cpp/vcredists_x86.asp

Re: Visual Studio 2005 DLL Hell

Posted 2397 days ago by Paul Sanders • • wwwReply

My solution to this problem is simply to link with the static libraries. For an application of any size, the extra overhad (about 100k) is not a big issue. You do miss out on any Windows updates, but that might be a good thing - at least you know that the runtime library is not going to change behind your back.

Also, rather than using MT, you can embed a manifest resource in you app by referencing a text file containing the XML in your .RC files (as a TEXTINCLUDE 3 resource). I do this to control how UAC works with my installer under Vista (which is a whole other can of worms), and if you do it with MT it generates .EXE's which crash XP (!) (see http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=463884&SiteID=1).

Re: Visual Studio 2005 DLL Hell

Posted 2341 days ago by Latchezar Tzvetkoff • • • Reply

Is there a way to set up Visual Studio 2005 to link my applications with another runtime library? I mean, to set it from the Visual Studio itself, not to replace the spoken libraries and headers.
I've found a `solution', to ignore all default libraries and to use my C headers (stdio, etc), then link with my own CRT implementation and everything works just fine, but I got to do this with every project I start, or maybe make a template?

--
Regards...

Re: Visual Studio 2005 DLL Hell

Posted 2064 days ago by Kevin J Conway • • • Reply

A million and one thank yous. It took a while to find this page, but it was the spot on answer to getting Perl's DBI and DBD::ODBC modules to comoile in the stripped down Perl that ships with a vendor's implementation of Perl.

The solution was definitely in fixing the MM_Win32.pm file.

This is, to say the least, awesome.

kjc

Re: Visual Studio 2005 DLL Hell

Posted 2056 days ago by Pushkar • • • Reply

Hey! Nice post.
Just had a small doubt. I want to create a client side Win 32 service. It should be able to run without .NET support. So is it OK if i make it using Visual Studio 2008 Express edition?
Please reply.
Thanks!

Re: Visual Studio 2005 DLL Hell

Posted 1870 days ago by acai • • wwwReply

I would like to run VCRedist_X86.exe from another program (using ShellExecuteEx) but in quiet mode. However, the /Q option to the VCRedist program does not work. Is there a fix for this?

Re: Visual Studio 2005 DLL Hell

Posted 1703 days ago by John • • wwwReply

Thank you Tim. The same solution Kevin J Conway helped me to correct that error in VS.

Re: Visual Studio 2005 DLL Hell

Posted 1505 days ago by Josue Gomes • • wwwReply

Thanks a lot. This article is still useful 4 years later.

Re: Visual Studio 2005 DLL Hell

Posted 1469 days ago by Larry Phegley • • • Reply

I shifted over to the /MT and included LIBCMTd.lib on the exclude line and I'm still getting the requirement to have the MSVCR80.DLL . What am I doing wrong?

Re: Visual Studio 2005 DLL Hell

Posted 1247 days ago by utangac • • wwwReply

My solution to this problem is simply to link with the static libraries. For an application of any size, the extra overhad (about 100k) is not a big issue. You do miss out on any Windows updates, but that might be a good thing - at least you know that the runtime library is not going to change behind your back.

Re: Visual Studio 2005 DLL Hell

Posted 1246 days ago by Arnel • • • Reply

I would prefer static linking to CRT and other standard static libraries in order to avoid DLL HELL and other potential dependency problems. If larger compiled binary size is a concern as a result from static linking, then read the article found in this site:

http://www.catch22.net/tuts/minexe

One of the most important hint that I've got here is to enable the linker switch /FILEALIGN:512 either through command line or within the Visual C++ IDE.
This linker setting would reduce the size of the compiled binary quite considerably.

For me, static linking is the best way if we want less or no hassle at all in deploying our applications built using Visual Studio 2005 especially if changes in the runtime library won't be a problem.

I strongly agree with utangac's response to this forum.

Re: Visual Studio 2005 DLL Hell

Posted 1072 days ago by Mike Dornelas • • wwwReply

One of the most important hint that I've got here is to enable the linker switch /FILEALIGN:512 either through command line or within the Visual C++ IDE.
This linker setting would reduce the size of the compiled binary quite considerably.


Comments are closed

Recent posts

Users plead with Borland to give up .NET
IE7 to be released 18th October,...
If Microsoft doesn't use UAC, why...
Google's unsettling lack of direction
Vista security: now prove it


Powered by bBlog