On Windows editions that support x86 emulation, there are two directories for program files. The C:\Program Files directory is for programs in the native system bitness, and the the C:\Program Files (x86) directory is for programs that run under the x86-32 emulator. But why are they separate directories? Why can’t we combine them? If you have 32-bit Contoso and 64-bit LitWare, you can still put them in C:\Program Files\Contoso and C:\Program Files\LitWare, and they won’t bother each other.
That’s true, but it does create problems if a program is available in both 32-bit and 64-bit versions, such as Microsoft Office or Visual Studio. You couldn’t install both versions side-by-side; you’d have to pick one.
And it so happens that Windows itself comes with a lot of programs that are available in both 32-bit and 64-bit versions, like Internet Explorer and WordPad. Those programs could have installed themselves into separate directories like C:\Program Files\Internet Explorer and C:\Program Files\Internet Explorer (x86) to avoid the conflict, but then that runs into compatibility issues with apps that do things like launch %ProgramFiles%\Internet Explorer\iexplore.exe and then start manipulating the Internet Explorer process expecting it to be the same bitness as the program that did the launching.
This sounds sort of like a lazy answer, seeing as this problem could be solved with sufficient application of application compatibility shims. But application compatibility shims are really a solution of last resort, because by their nature, they can be applied only to programs where the problem has already been identified. If there’s a way you can structure your system so that these problems never arise in the first place, then you don’t have to worry about identifying the programs that suffer from the problem: You fixed all of them at once!
Yet another problem is with the pesky Common Files subdirectory under Program Files. This is a directory that is intended for the case of separately-installed programs which nevertheless share some things in common. For example, Contoso might have two products, Contoso Standard and Contoso Deluxe, and both of the programs use the Contoso Framework. The Contoso Framework files can go into the C:\Program Files\ subdirectory.
If the 32-bit and 64-bit directories were combined into a single C:\Program Files directory, then you would have a mix of 32-bit and 64-bit components in C:\Program Files\, and that makes nobody happy. Whoever installs first wins, and whoever installs second gets errors.
Keeping the two Program Files directories separate avoids this problem. C:\Program Files\ contains the 64-bit Contoso Framework files, and C:\Program Files (x86)\ contains the 32-bit Contoso Framework files.
After I wrote up this answer, I realized that I already answered it some time ago, so here’s the video:
There are three Program Files folders.
The article missed C:\Program Files (ARM).
When Apple will’ve entirely moved on from x86 in less than 2 years (3rd party apps excluded). After 6 years Microsoft seems to be giving up on ARM. Like UWP is supported but has little focus :(.
I think you may be confused.
On systems where there is a Program Files (ARM) directory, the system native directory (Program Files) is actually ARM64. Program Files (ARM) is there for the 32 bit ARM Windows on Windows subsystem, and that was never fully embraced.
64 bit ARM is a different story.
But I wish they had chosen P and P86; so much extra typing and paths that go on forever.
https://devblogs.microsoft.com/oldnewthing/20131119-00/?p=2623
but parts of me also believe it was to show (and require) support for long names and spaces in paths.
Lost me as soon as you said x86 emulation. The last time I checked, all Intel and AMD processors still start in 16 bit real mode and go from there. The x86 emulation is NOT an emulation mode but part of the processor’s instruction set.
If Microsoft ever starts supporting this on non-Intel instruction set based processors (AMD is part of this) then it will be an emulation mode.
I really think you should be careful when using a completely unqualified "all". It allows some awkward person to come along and ask "So you are saying that if I go and boot a computer with an Intel 8080 processor, it will start in 16 bit real mode?"
There is also the interesting case of that time that there were Windows versions that could run on an Intel processor but couldn't natively run code built for 8086 or newer processors. Windows Server 2003, 2008 and 2008 R2 all had IA64 processor support. The early Itanium processors had hardware x86 emulation...
There’s more to 32-bit emulation than executing 32-bit CPU instructions. You have to recreate the entire 32-bit execution environment: DLLs, registry keys, threads, I/O, etc. When you write an emulator for old computer systems, executing the CPU instructions is arguably one of the easiest parts. Much harder is stuff like I/O timing.
So why are there not separate Program Files and Program Files (x64) on ARM64 Windows edition where the native system runs ARM64 code asn there’s a an x86-64 emulator?
What do you suppose happens if I try to install a program that is available both in ARM64 and in AMD64? For example, Visual Studio Code, 7-Zip, Python, et cetera et cetera?
The idea behind this is that you should only choose to install the ARM64 version. AMD64 emulation is only there if there is no other option.
This works because the ARM64 rules are different. First, all of the system libraries are what can be classed as "FAT" binaries. The ARM64 libraries have both ARM64 and x64 code in there. This means that if an ARM64 application loads it, it will use the ARM64 entry points. If an x64 application loads it then it will use the x64 entry points.
For interoperability, as already mentioned, x64 is able to load ARM64...