Why are there separate Program Files and Program Files (x86) directories?

Raymond Chen

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\Common Files\Contoso 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\Common Files\Contoso, 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\Common Files\Contoso contains the 64-bit Contoso Framework files, and C:\Program Files (x86)\Common Files\Contoso 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:


Comments are closed. Login to edit/delete your existing comments

    • Mystery Man 0

      The same problem applies to Visual Studio. Traditionally, it has always been 32-bit. The latest version is exclusively 64-bit.

    • Alex McCaffrey 0

      The article says you can’t install Office both 32-Bit and 64-Bit Office.

  • Rand Random 0

    Maybe some new questions would be what the future might bring? Are we ever getting a 64Bit only windows? Will streaming and product as a service remove the necessity to install applications? Will everything be dockerized, sandboxed, without overlapping issues?

    • Brian Boorman 0

      [quote]Will streaming and product as a service remove the necessity to install applications?[/quote]

      Never. At least for people who use a PC for more than just browsing the web.

      Edit: If this platform doesn’t support bbcode, then how do you quote from previous comments?

    • anonymous 0

      This comment has been deleted.

      • skSdnW 0

        Your dream already came true. On Windows 10 you can declare in your manifest that you want utf-8 and then all A functions treat CP_ACP as utf-8.

  • Harry Johnston 0

    One catch that ICT support and system administrators need to be aware of is that you can’t just assume that everything inside Program Files is 64-bit and everything inside Program Files (x86) is 32-bit.

    There are a fair number of 32-bit programs that install themselves in Program Files, presumably due to the use of a hard-coded path.

    I also know of at least one application that, when upgraded from 32-bit to 64-bit, leaves itself installed in Program Files (x86), even though a clean install of the 64-bit version goes into Program Files. (Presumably this is done for the benefit of any already-installed plugins or third-party products with a dependency on the application in question.)

    • Neil Rashbrook 0

      The application I’m thinking of doesn’t have plugins, and third-party products would surely get confused by the bitness change anyway. (It also self-updated itself from 32-bit to 64-bit, but it’s unclear whether that’s what you meant.)

      • Harry Johnston 0

        In the case I was thinking of (a web browser) the plugins are bitness-agnostic and the hypothetical third-party products would typically launch this application via a command line so shouldn’t care about the bitness either. But sure, there may well be other reasons why it is more convenient for an upgrade to leave the application in the same folder even if the bitness has changed. It might even have just been an oversight on the developer’s part.

        (I don’t think it made any difference whether the product was updated by hand or self-updated, the behaviour was the same either way.)

        • Raymond ChenMicrosoft employee 0

          It’s not unheard of to launch a web browser and try to inject a DLL into it. Or to embed a web browser inside another app.

    • Yuhong Bao 0

      Do they really bypass WOW64 redirection to do this?

      • Harry Johnston 0

        There is no WOW64 redirection for the Program Files folders.

        Applications are expected to look up the path to Program Files using an API such as SHGetKnownFolderPath, and a 32-bit application will be told that the path to use is C:\Program Files (x86) instead of C:\Program Files. But if the developer didn’t bother following the rules, and the installer just uses a hard-coded path to C:\Program Files, Windows won’t redirect the files.

  • Alexis Ryan 0

    It is unfortunate that System32 is the system directory for the Native files but it makes sense as System was already used by 16 bit Windows so 32 bit Windows NT obviously needed a new one and at the time System32 would have been a good choice for the new 32 bit Windows NT and it stayed ever since even if the number no longer has any meaning for bitness. Maybe they should have used SystemNT instead it would have reduced some future confusion that now exists

    • Neil Rashbrook 0

      I think I’ve already asked why System became System32 but not subsequently System64; I’ve forgotten what the answer was, although I’m sure a search engine would be able to find it.

      • Chris Iverson 0

        Like many seemingly odd choices for Windows, compatibility.

        There’s literal decades of applications out there that hardcoded “system32” as the path to the system binaries.

        To ease the transition in updating those programs to 64-bit, they don’t have to change those hardcoded paths. And the WOW64 subsystem will kick in for 32-bit apps, and redirect C:\Windows\system32 to C:\Windows\SysWOW64, so all applications can just ask for C:\Windows\system32 and get the files they need.

        Now, they shouldn’t do that; they should use the proper API for retrieving system folder paths, but practically speaking, we all know how often “should” is followed.

    • Tim Weis 0

      Maybe they should have used SystemNT instead it would have reduced some future confusion that now exists

      “Hey, what’s the ‘NT’ in ‘SystemNT’ for? I’m running a clean install of Windows 95.”

  • Miika Seppälä 0

    Isn’t “emulation” a bit misleading term? As far as I know, modern 64-bit x86 CPUs are still backwards compatible with old 32-bit code. The CPU just executes 32-bit programs in a different mode.

    “Emulation” suggests there’s some software running and translating 32-bit code into 64-bit.

    • Antonio Rodríguez 0

      It isn’t clear in the article, but the video explains that the decision was taken when developing non-x86 64 bits Windows (Alpha and Itanium already had 64-bit support even before AMD launched the AMD64 architecture; MIPS and ARM would come later). In those architectures, running x86 software is achieved by emulation, because those CPUs do not have x86 binary compatibility. Thus, it’s proper to talk about “emulation” in this context: AMD64 processors being able to run x86 software directly is the exception to the rule here.

    • Pavel Kostromitinov 0

      It’s not “32-bit instructions emulation”, it’s “32-bit Windows emulation”

  • conio 0

    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?

    • Me Gusta 0

      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 libraries if they are correctly generated. These would be libraries marked as ARM64X and are linked from object files generated for both the x64 compiler and the ARM64 compiler. But the opposite is true too, if your application uses plugins and expect that the plugins may not all be updated then the application can be built as ARM64EC. This allows the application to load x64 libraries. This is how the ARM64 version of Office works.

  • Michael Ober 0

    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.

    • Raymond ChenMicrosoft employee 0

      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.

    • Me Gusta 0

      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 support, but the newer Itanium processors all required the WoW64 layer to emulate.
      Finally, if I go and grab a Surface Pro X, which has an ARM64 processor, and check things, it has things like a Program Files (x86) directory, a SysWow64 directory and other indicators that it is able to run x86 code. If I look at task manager, there are things that have (32 bit) after them, and if you check the binaries then you will see that they are x86 binaries. So yes, Windows does do this on ARM64 and yes, it is x86 emulation.
      It feels that in this case you had the view that Intel = Intel 8086 and newer, and for some reason Windows = x86/x86-64 only.

  • Malcolm Windham 0

    But I wish they had chosen P and P86; so much extra typing and paths that go on forever.

  • Alex McCaffrey 0

    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 :(.

    • Me Gusta 0

      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.

Feedback usabilla icon