« Who wants shotgun? | Home | How To Destroy Your Music Collection »

Individual Entry With Comments

July 24, 2007


Filed under Programming

The Problem

At work, we recently upgraded to Visual C++ 2005 Service Pack 1 (SP1). At the same time, our application stopped working for some users.

Everybody that had SP1 was able to run the application. Some people *without* SP1 were also able to run the application.

My system (not SP1) could not run the application built by the newly upgraded SP1 build machines, so I tried to figure out why.  I used Dependency Walker to find out why my application would not load.

Dependency Walker showed that the C runtime library (msvcr80.dll) could not be found. I noticed the full path of where the application was trying to get msvcr80.dll was:


I searched my system and I *did* have msvcr80.dll in my \windows folder, but not in the path the application was using.

I had not seen a path like that before for a DLL. I had no idea why the application was looking there instead of in \Windows\system32 like it normally would.

I tried copying msvcr80.dll locally to the application folder and refreshed Dependency Walker. That had no effect...the application could not find msvcr80.dll.

That used be the failsafe way to make an application see a DLL...put it in the same directory as the application. Something was very different now.


The Cause

Something had changed. It was Microsoft's answer to DLL Hell that was introduced with Windows XP: side-by-side assemblies (winsxs).

Visual C++ 2005 is the first version of Visual C++ that uses side-by-side assemblies for the C/C++ runtime libraries.

The definition of an assembly is not straight forward. For the purposes of this discussion, I'm going to consider an assembly the collection of DLL's that make up the C runtime library.

Side-by-side assemblies changes where a DLL is stored for global access. Instead of using C:\Windows\System32, they are stored in the side-by-side directory, C:\Windows\winsxs.

The advantage of winsxs over system32 is that you can have more than one version of a particular DLL with the same name. With system32, you had to overwrite a DLL if you wanted to add a new version with the same name. Winsxs uses directories with version information to isolate DLL's from each other.


In the above picture I highlighted 4 directories. These 4 directories contain 4 versions of the C runtime DLL's. Each directory contains the same three C runtime DLL's:

  • msvcr80.dll: C runtime library
  • msvcm80.dll: C runtime library for managed code (i.e. .NET support)
  • msvcp80.dll: C++ runtime library

All of these DLL's end in 80 because they are from Visual C++ 8.0 (a.k.a. Visual C++ 2005). The prefix is from MicroSoft Visual C (msvc).

The directory name is used when an application wants to load a particular version of the C runtime library. The directory name contains various pieces of information about the DLL's inside. Each piece of information is separated by an underscore. For example, consider this directory:


  • x86 (processor architecture): Built for x86 (32-bit Intel Processor and compatibles)
  • microsoft.vc80.crt (name): Microsoft Visual C 8.0 C RunTime
  • 1fc8b3b9a1e18e3b (public key token): A unique ID for C Runtime
  • 8.0.50727.762 (version): Version of the DLL's (right click on the DLL, select "Properties", and then the "Details" tab, and you should see this number)
  • none (language): The language these DLL's are designed for
  • 10b2f55f9bffb8f8: Not sure, but I assume this is a unique ID for this particular version of the DLL's

So how does an application know what version of a DLL it needs to load? That is where a "manifest" comes into play. A manifest is an XML file that contains information used to create the directory in C:\Windows\winsxs so that a particular DLL can be loaded. If you write an application that uses the C runtime library (99% of the time you will), then you are going to need a manifest.

Here is the manifest for an application designed to work with the above C runtime (auto-generated by Visual C++):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

The main line that is of interest is the "assemblyIdentity", which contains a "name", "version", "processorArchitecture," and a "publicKeyToken" like the above example winsxs directory.

There are two ways to store a manifest:

  1. External .manifest file. The manifest file has the same name as the .DLL or .EXE, with ".manifest" added on to the end. For example, helloWorld.exe would have an external manifest called "helloWorld.exe.manifest." The manifest is located in the same directory as the .EXE or .DLL.
  2. Embedded manifest. This is the default option for Visual C++ 2005. The XML file is store as a text resource in the .EXE or .DLL.

To chose an embedded assembly or external file, go to Visual C++ 2005 -> Project -> App Properties -> Configuration Properties -> Manifest Tool -> Input and Output -> Embed Manifest -> Yes or No.


Once an application is built, you may want to change which DLL's it is using. How do you change a manifest without rebuilding the application/DLL? For an external .manifest file, just edit the .manifest file and you are done.

Changing an embedded manifest is a bit more tricky. Here's what you do:

  1. Create a text file that has the manifest in it that you want to use.
  2. Select all the text and copy it to the clipboard (we'll use it later)
  3. Visual C++ 2005 -> File -> Open -> File...
  4. Select the .EXE or .DLL you want to modify and click "Open"
  5. The manifest is stored in a resource called "RT_MANIFEST" with an ID of 1. Double-click the "1" to open it in an editor.
  6. Ctrl-A to select all the text in the editor
  7. Ctrl-V to overwrite the text with the text in the clipboard.
  8. Ctrl-S to save the updated text in the .EXE/.DLL


The search order for DLL's has changed with winsxs. Now side-by-side directories (\windows\winsxs) are searched even before the local application directory. Here is an article about search order.

Since the winsxs directory is searched before the local application directory, it is impossible to override a .DLL in a winsxs directory, right? WRONG! This article shows how to do it. Basically, you just remove "public key token" from the application manifest and then create a manifest file for the DLL's you want to use (an assembly), like Microsoft.VC80.CRT.Manifest.

You may know the name of the DLL's you are interested in, but what is the assembly name for these DLL's? This page has a nice list of assemblies and the DLL's they point to.

I showed you earlier how to change a manifest without rebuilding an application. The next time you build the application, your manifest changes will be overwritten by Visual C++. To make your manifest changes permanent, you need to update the project settings so they are output every time you build your application.

To add information about an assembly to the application manifest...

  1. Visual C++ 2005 -> Project -> App Properties -> Configuration Properties -> Linker -> Manifest File -> Additional Manifest Dependencies
  2. In this text box, put the contents the <assemblyIdentity>, but leave out the <assemblyIdentity> open and close tags.
  3. Replace all double quotes with single quotes
  4. Enclose the entire line in double quotes

If I wanted to put the following into the auto-generated manifest file for an application...

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        processorArchitecture="x86" >

...then just put this line in "Additional Manifest Dependencies"...

"type='win32' name='Microsoft.VC80.CRT'
  version='8.0.50727.762' processorArchitecture='x86'"


The Solution

So why were some people able to run the application even though they did not install SP1?

It appears that people that installed iTunes were able to run our application without SP1 installed. My theory is that version of iTunes was built against the SP1 C runtime and it installed the proper DLL in winsxs.

How did you get the application to work for people without SP1?

We decided to check to see what versions of the C runtime were available on a users system. If the version was older than the version our application was built against, we installed the SP1 C runtime libraries via the Microsoft Visual C++ 2005 Redistributable Package (x86).

  • For Visual C++ 2005, use this
  • For Visual C++ 2005 SP1, use this

Do you have to install the SP1 runtime in order to get an app built with SP1 to run?

That is certainly the preferred method, but you can also put the DLL's in the same directory as the app and bypass winsxs. One reason to not bypass winsxs is that if Microsoft pushes a fix for libraries that may have a security issue, you won't ever get the updates an your application will be left with the security holes.

We found another way that lets you work in the safety of winsxs on systems that may not have the same runtime libraries. Instead of using an explicit version of the C runtime (which requires that exact version present on your computer or else the application will crash on startup), there is a version that means "use the most recent compatible version of the C runtime". If we would have used this version in our application, it is likely that users would be able to run the application even if they don't have the SP1 C runtime library present. To get this "special" version, find the appropriate .manifest file in the C:\Windows\Winsxs\Manifests directory. Open this file and you will see a line with the XML tags "<bindingRedirect>". Basically, if you use a version in the range of "oldVersion", then the actual version that is loaded is given by "newVersion". I learned about this technique from this forum post.



In my case, versions 8.0.41204.256 through 8.0.50608.0 and 8.0.50727.42 through 8.0.50727.762 mapped to 8.0.50727.762. If you can find a version that always maps to a valid version via <bindingRedirect>, then use this version in your application's manifest and your app should work regardless of which versions of the DLL's are installed. You will need to check your user's machines to make sure they all redirect correctly in order for this method to work.



I knew *nothing* about winsxs (windows side-by-side) on Friday. It is a mess of complex topics that most people don't understand. There is a lot of information on the internet about winsxs, but it is spread all over the place and varies in degree of helpfulness. I'm certainly no expert, but I've learned a lot in the last couple of days.

Now that I understand the problem that winsxs is fixing, I can appreciate it, even if it is very messy and hard to understand.

The net result is applications will be more stable and reliable as more and more applications switch to winsxs. This is a good thing.

I wrote all this down mainly because I knew I'd forget about by the time I needed to address winsxs issues again. Hopefully this is helpful to others as well.

Comments (43)

Mike Schriever:

Interesting. Even I was able to follow along. I can now say, with confidence, I will never have any use for this information.


That was a good piece of information.
If have a Winsxs folder of 3.37 Gigs on my drive.. and was going to delete it because its just so huge..
thanks to you.. I appreciate what microsoft is trying solve :)


So what?
Will winsxs folder be grow in size day by day?
How can we decrease its size?

This folder is just like a cancer tumor growing in size day by day.


> Will winsxs folder be grow in
> size day by day?

As you patch your system and install software, winsxs will continue to increase in size.

> How can we decrease its size?

I haven't looked into this.

You'd hope that uninstalling software will also remove any files that were placed in winsxs...but its likely that many uninstallers won't do this.

Deleting files in winsxs could cause applications or the os to crash...so I wouldn't recommend it.

I'm not sure how to detect unnecessary files in winsxs. If an app puts a file in winsxs, then there is probably a list of what applications depend on which files.

If a file has been updated, you'd hope that the old unused one is removed...but I don't know how this is dealt with.

It is also possible that the winsxs directory contains languages or processor architecture (32 bit vs 64 bit) that you don't care about...and it seems like these could be removed.


Although versioning is a good idea, I don't particularly like how they tried to solve it (I don't doubt the system will change the coming years). It's quite bloated, esp on the development side.
Also, the errors that result when things don't go as it should be are extremely uninformative, plus the fact that it works differently on XP & Vista is a nuisance. Could have done without that.
But somehow, Vista's doesn't know a lot about backwards compatibility.

A system where at least you'd get hints on what it's trying to load and descriptive errors (instead of 'please reinstall'!) would have helped a lot of people. Guess that's not how MS thinks unfortunately (too busy with marketing).


Do you know of any other versioning implementations? I'd be curious to see other approaches to this problem.

What part is bloated?

I agree the error message ('please reinstall') is not very helpful. An extra line that says "trying to load version X of dll (based on manifest loaded from Y), but only could find version Z" would give developers a better idea of why their app doesn't work on a particular system.

How does winsxs behave differently on Vista vs. XP?


I'm troubleshooting a problem that I encountered in Sandboxie utility.

It was caused by trying to run a .dcr file in AM Browser. It opened an endless chain of itself, forcing me to unplug the computer.

After restarting, Sandboxie would not operate because of "Name buffer is approaching overflow"

I reinstalled the OS, no effect.

I traced the file execution, and find out it could be the WinSXS library. So I'll delete that directory, and try reinstalling the OS again. I'll have to delete all the registry traces, too, to make sure it won't bug me again.

Robert...I have no idea what Sandboxie, AM Browser, or .dcr is...but I *do* know that deleting your winSxS directory is *not* the solution!

If the application was created wrong, I'd talk to the developer and see if he can get you one that doesn't have a problem. If you can't do that, you can read my post about how to modify the manifest for the .exe to point to another .dll than the one it is looking for.

Good Luck!



@ David
Taken from http://www.fileinfo.net/extension/dcr

.DCR File Extension --
Uncompressed image saved in Kodak's RAW image format; used by Kodak digital cameras (typically SLRs) for capturing photos without any compression or color adjustments.

RAW photos can be edited more accurately than .JPEG photos after they have been saved to the computer.


Why are you still using AM Browser? The last stable release was released 07/29/2005 and a beta was released 02/12/2006.

AM Browser was a good browser that used IE engine to render pages. The biggest advantage I found using it was that you could have an IE browser with tabs. At that time IE 6 did not have tabs. Since then IE 7 has come out and has tabs.

If you don't like IE, Firefox has tabs too.

So why do you still use AM Browser? It's a browser that has not been updated for over 2 years. The browser might be your problem.


Dave, if I have my own DLL shared by multiple apps, during deployment on XP, I just copy it to system32. What should I do on Vista, how can I make it work with WinSxS folder?


I actually have never created my own side-by-side assembly...but I expect I will in the future.

I just searched the net and the best I could find was this.

Hopefully people like you will post your results so we all can learn!

Good Luck!



i can think of a MUCH better solution.

REQUIRE all DLL's to do this


problem solved...


propably am asking about basic understanding. Could you let me know how one can create a manifest and place the native dll into WinSxS?



The advantage of winsxs over system32 is that it's roughly eight times larger.


A few problems with your suggestion...

What if somebody else installs a dll in the \windows\system32 directory with the same name as your dll? Your app will break.

If you want all the version information that winsxs contains, then you would need to call your dll something like this...

msvcrt_x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_ 8.0.50727.762_none_10b2f55f9bffb8f8.dll

...which is a mess.

What if you do a bug fix to your dll and it fixes some apps and breaks others? With winsxs you could have some apps use one version of your dll and others use another (even if they have the same name)...without modifying anybody's app.

I agree it is messy...but I understand why it is like this and I think it means applications are less likely to break.

BTW...I don't see a reason to use winsxs unless you are making a dll that lots of applications will use (like the C runtime library). Most developers will keep their dll's with the application without a need for winsxs.


I have never made my own "Side by Side Assembly."

If I was, this is where I would start...


If done right, winsxs should not be any bigger than system32...it should be the minimal set of dll's needed to run the apps on your system.

Nothing enforces this policy, so my guess is we have lots of dll's on our system that we won't ever need.

For example, I see I have lots of Russian dll's in winsxs (directories with "_ru").

Windows should have a utility that verifies what is installed in winsxs is actually needed.


@David: This is my point. I've yet to gain any advantage of this advanced system, because for me, it only serves to store endless copies of unused resources, that I have absolutely no control over.

I've noticed that things getting added to winsxs is really tightly knit with running installation programs. I did two fresh installs of Vista Business, and installed Psycle (a music sequencer software) on both. Then I installed the VST instruments and effects that I use on one, and copied the VSTPlugins-folder from the first to the second (so both Vistas now have the same files, but on one, the files were installed with installers and on the other they were copied manually).

The latter set-up now has a winsxs-folder that is some 450Mb smaller than the former setup. Both computers run Psycle and all plugins flawlessly, so the difference in user-experience is zero. The only difference is, that one computer has less disk-space due to un-installer data and winsxs.

Now when this is multiplied by installing Adobe CS, Firefox, Visual Studio and XAMPP, we get my winsxs folder, which takes up 17 gigabytes..


Let's see. An application is bound to a specific version of a DLL, and a later version of that DLL corrects a serious bug. Now the new version is installed into WinSxS, but the application just keeps using the old one.

So we have the situation that installing new DLLs have no effect on applications, without a new "version" of the application with only a modification to the manifest.

Why not use a system similar to the UN*X convention of having library files with fully qualified names, and using links from less qualified names to the latest matching version.

One could have actual files (from the WinSxS on my laptop)

and links
msvcrt_7.0.0.dll -> msvcrt_7.0.0.0.dll
msvcrt_7.0.10.dll -> msvcrt_7.0.10.0.dll
msvcrt_7.0.2600.dll -> msvcrt_7.0.2600.5512.dll
msvcrt_7.0.dll -> msvcrt_7.0.2600.5512.dll
msvcrt_7.dll -> msvcrt_7.0.2600.5512.dll
msvcrt.dll -> msvcrt_7.0.2600.5512.dll

This way developers can link against whatever they feel like the most convenient compromise between flexibility and compatibility.

Libraries usually have some conventions about version numbers, like X.Y.Z, where Z is for bug fixes, Y is for additional features and X is for binary compatibility. An application that only uses some basic features from version X can link against that. Another application that requires some advanced feature from X.Y can link against that. If one's paranoid, one could link against X.Y.Z.

Anyway, if Microsoft can't keep their libraries compatible across changes to the *fourth-order* version numbers, the game is truly over. The way it's used, WinSxS seems to be a fix to a problem that shouldn't exist in the first place.

And what's with these numbering schemes? I mean, Microsoft.VC80.CRT v8.0.50727.1433?

It is not natural to be needing workarounds for compatibility problems between versions 8.0.50727.42 and 8.0.50727.1433. This not only a waste of disk space, but a waste of memory as well, with applications loading separate copies of very slightly different library files. If this is the way, we could just as well give up on the whole concept of DLLs and stick to static libraries instead.


I see some problems with the *nix approach:

How do you handle two files with the same name that contain different versions? E.g.: Two apps link against msvcr90.dll, but need different versions of that dll.

What about different languages? For example, you may use both English and Spanish versions of applications on the same system. These apps may use the same libraries, but are different only in the translated strings.

What about different processor architectures? If you are running 64 bit, you may have some apps linked against 64 bit libraries and other apps linked against the 32 bit versions of the same libraries.

What about name clashes when two companies use the same file name for a library?

But probably the most important issue is backward compatibility: FAT32 doesn't support symbolic links...so your solution won't work for people stuck with that old file system.


>The way it's used, WinSxS seems to be a fix to a problem that shouldn't exist in the first place.
I am absolutely agree with this, microsoft is just actually avoid the problem instead of solving it. Anyway in this era of big hdd's and fast computers there no one care about optimisation. One jast care about how to proove necessity of new hardware. ;)
At least they could try to create tool for removing unused dependency libs.

1. Program can always install dll in it's own directory and it'll have priority over the system dir so uninstalling app = uninstalling dll which don't work with sxs because dll's considered as shared.
2. For different architectures they can create System64 dir or use some kind of x64 - x86 file naming trick.
3. For localisation already exists MUI ideology.
4. Resolved as in 1 but installing dll in common for given company dir.

I understand that this way is not so good as it seems too, but at least it provide possibilities to maintain system resources instead of collecting enormous "side waste".


I don't think your suggestion solves the problem.

Since you can't assume anything about a system32 DLL and what version it is, you would have to install *every* DLL locally to guarantee your app will run.

Installing every DLL locally won't work because of the massive amount of hard drive space needed.

For example, consider notepad.exe.

It is only a 151 KB application.

However, it uses 125 DLL's that total over 75 MB of space (according to dependency walker).

Solitaire.exe also needs its own unique 125 DLL's that use more than 75 MB of space.

I checked my system: I have over 4,000 executables. If each needs 75 MB of local DLL's, then I'd need 300 GB of hard drive space just for executables.

Also, local DLL's mean RAM is used for multiple copies of the same DLL. You won't be able to fit as many apps into memory as you can when DLL's are shared.


Excellent article! Thanks for sharing the info.


I thought I'd share a page that deals with a very tricky WinSxS problem that I had today. This is the reason for the R6034 error (in some cases at least):

Steve Heck:

Is there any way to add the policy file content via "Additional Manifest Dependencies"?

When I upgraded to VC++ 2008 SP1 I can no longer run my application without installing the VC++ 2008 SP1 Redist Package. This was not the case with VC++ 2008 No SP. I only needed to include the redist libraries and manifests supplied at: Program Files\Microsoft Visual Studio 9.0\VC\redist and I could run on a system without VC++ 2008 Redist package.

It appears the bindingRedirect is needed for SP1.

Steve Heck


@David re Reino's post

As I interpret it, he's not describing a solution to DLL hell for already-written programs. Rather it's what MS should have set up as the convention in the first place, preventing the entire issue from arising.

The use of non-unique DLL names (and references thereto in apps that aren't prepared to use any of the DLLs bearing that name) IS the problem. DLL hell is the result of MS's initial lack of foresight, and patchwork-fix mentality since.

Gee, let's get around it by sticking the duplicate filenames in separate folders, and make developers specify which folder they want. How is that easier than making developers simply link to a more specific DLL filename??

They've had the simplest solution sitting in front of them (on every *nix box) the entire time. Sometimes I wonder if they want to keep app development (and use, for that matter) more difficult than it needs to be, as a business strategy for a company with extreme market-share.


P.S. That said, I didn't know anything about this side-by-side business until reading this blog. So, thank you for it! :)

(Heh, got a little excited and forgot. :-p)


OK, reality check here folks. This is a day of 1 Terabyte hard drives under $100.00 Why does a little 3 to 6 Gig directory bother you?

Stop worrying about it. Even if it did grow, it would never get big enough to be a concern.


Ok.. to answer the last post "this is the day of 1 terabyte hard drives..." Some more savy user partition there drives into compartments. And if you happened to make a 30 gig partition for the 5 gig OS and it has grown to 30 gigs and there is no way to delete the data, you cant download Microsofts SP2-which may actually fix this design error.


Excellent article. Thanks for posting.


A very usefull and informative article. Good work.


Steve Terapak:

Thanks for the info helped me solve a strange annoying problem.


here are other informations about DCR at http://www.file-extensions.org/search/?searchstring=dcr


I have created manifest file for my.dll. my.dll has a dependency on msvcr90.dll. In auto generated manifest file contains, ( i was using MS VC++ 2008 Express Edition)

In side by side(winsxs) directory, there are three version on msvcr90.dll. my.dll started to using only the latest version of msvcr90.dll (9.0.30729.4148).

Here in below topics i need the help:

1) my.dll is using only the latest version of msvcr90.dll . if i tried to make this dll as old. My application fails to start. How to make contidion that my.dll should refer only to the version which i mentioned in manifest file.

2) how can i tell my.dll should dependent on the msvcr90.dll which i providing in the local directory along with my.dll. I want to restrict my my.dll should not do search in the system directory for the msvcr90.dll.

1) See the section in the original post about redirects. I haven't done it myself, so good luck.

2) See the section in the original post about bypassing WinSxS.


Im tring to create a manifest for my own.dll, i took the manifest file from C:\WINDOWS\WinSxS\Manifests for example. In that, below tag was one of the line.

In above tag, hash value was assigned with 40 character. Here comes my doubt, 1) hash value was auto generated, if not, whats it points to?

I haven't tried to make my own manifest yet.

Michael Barth:

Great Help, thanks a lot


ok...so howw do i remove MS's overwrite proction so i can format my HDD for a clean install bcus i have over 7 GBs of non removeable winsxs files that gets copied right back in?

I would boot from the install cd and format the drive.

Mark MacVicar:

I tried the method for overriding the winsxs assembly specified here http://blog.kalmbachnet.de/?postid=80, but couldn't get it to work. Let me know if you have any tips.

Monika Huk:

Thanks a lot - this comprehensive article saved my day - esp. the information on how to edit the manifest of a dll where I do not have the source code :-)

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)


This page contains a single entry from the blog posted on July 24, 2007 1:45 AM.

The previous post in this blog was Who wants shotgun?.

The next post in this blog is How To Destroy Your Music Collection.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.34