The Big Picture: Two Programs, Two Versions, One Name
Sharing is great, until two programs want different versions of the same file. Program A was built for lib.dll version 1. Program B needs version 2. Both files are named lib.dll. Which one does Windows keep?
It is like two cooks who both borrow "the red cookbook", but there are two different editions. If someone swaps the edition, the other cook's recipes stop working.
7.1 The DLL Versioning Problem: "DLL Hell"
What it is: DLL hell is the nickname for the pain that came with shared DLLs in older Windows (the 1990s). It had a few typical causes:
| Cause | What happened |
|---|---|
| Overwriting | Installing program B put its newer lib.dll over the old one. Program A, which depended on the old behaviour, broke |
| Downgrading | An old installer put an older DLL over a newer one. Program B broke |
| Same name, different meaning | Two completely different DLLs shared one file name |
| Search order surprises | A different copy of lib.dll was found first (Section 4) |
BEFORE AFTER installing program B
C:\Windows\System32\ C:\Windows\System32\
lib.dll (v1) <- A works lib.dll (v2) <- B works, A BREAKS!
The problem is that a file name alone is not a version. Windows needed a way to ask for "lib.dll, exactly the one I was built for".
Ways Windows reduced this pain:
- Windows File Protection / Resource Protection guards important system files from being overwritten by installers.
- Local copies: a program keeps its own DLL in its own folder (the application directory is searched first, Section 4.1).
- Side-by-side assemblies: the real fix, described next.
7.2 How WinSxS Lets Many Versions Coexist
What it is: Side-by-side (SxS) means several versions of the same DLL live next to each other on the computer, and each program is given the version it asks for.
Three ideas make it work:
Idea 1: The assembly. An assembly is a bundle: one or more DLLs plus a description that gives the bundle a unique identity (name, version, processor type, and a public key token that proves who made it).
Idea 2: The manifest. A manifest is a small XML text file that describes an assembly or says what a program needs. Programs usually carry their manifest inside the EXE as a resource. It says things such as "I need version 6.0 of the Common Controls assembly". Here is a simplified idea (not a complete file):
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0" processorArchitecture="*"
publicKeyToken="6595b64144ccf1df" />
</dependentAssembly>
</dependency>Idea 3: The component store. Windows keeps all versions in a special folder: C:\Windows\WinSxS. This folder is the component store. Each assembly sits in its own sub-folder, with a long name that includes its identity.
C:\Windows\WinSxS\
├── amd64_microsoft.windows.common-controls_..._5.82...\
│ comctl32.dll (old look)
├── amd64_microsoft.windows.common-controls_..._6.0...\
│ comctl32.dll (new look)
├── amd64_microsoft.vc90.crt_...\
│ msvcr90.dll
└── ... (thousands of other folders)
(Names are shortened here; real names are longer. Treat this as a picture, not exact.)
How the right version is chosen:
Program starts
│
Loader reads its MANIFEST: "I need Common-Controls 6.0"
│
Asks the SxS manager: "Where is that assembly?"
│
SxS manager finds the folder in WinSxS
│
DLL is loaded from there (the other version stays untouched
for the programs that want it)
So program A gets comctl32.dll v5.82 and program B gets v6.0 at the same time, even though the names match. That is exactly the "side by side".
A famous example: The modern look of buttons and menus comes from Common Controls version 6. A program that does not ask for it in its manifest gets the old-style version, so the same Windows can show both looks.
Visual C++ redistributables as an example. Programs built with Visual C++ depend on runtime DLLs (for example vcruntime140.dll). Newer Visual Studio versions put their runtime DLLs in System32 and share them (hedge: Microsoft changed how this works over the years). Older runtimes (like the Visual C++ 2005 and 2008 ones) used side-by-side folders in WinSxS. That is why your Apps list may show several "Microsoft Visual C++ 20xx Redistributable" entries. Each one supports programs built with that version. Do not remove them unless you know nothing needs them.
Why WinSxS is big, and why you should not delete from it.
- It holds Windows's own components and their older versions (needed for updates and repairs).
- Many files in it are hard links: the same file appears in two places on disk at once, but the data is stored once. So File Explorer may overstate the folder's real size.
- Deleting files by hand can break Windows Update and repairs.
- If you need space, use Disk Cleanup (Clean up system files) or the DISM tool through Microsoft's own instructions. Do not delete by hand.
Windows-specific tip: Look, but do not touch. In File Explorer, open C:\Windows\WinSxS and just notice how many folders there are. It shows you how many versions Windows is quietly managing.
Is DLL hell completely gone? Mostly, for programs that use manifests. Problems can still arise when a program loads a DLL by name through the search order (Section 4), or when someone places a wrong DLL in PATH. Windows 10 and 11 also use servicing to update system components safely, instead of installers overwriting files.
Summary
| Topic | Remember this |
|---|---|
| DLL hell | One file name, many versions; one installer overwriting another's DLL |
| Assembly | A bundle of DLLs with a unique identity (name, version, architecture, key) |
| Manifest | XML text saying which assembly versions a program needs |
| WinSxS | The component store holding many versions side by side |
| Result | Each program gets the version it asks for |
| VC++ redistributables | Several versions may be installed, each serving different programs |
| Safety | Never delete from WinSxS by hand |