ARM64_Lab

What is Program Files (Arm) on Windows ARM64? The variable existed, but the folder did not

In this article
  1. Reading the same fields from ARM64 and x86 processes
  2. ProgramFiles(Arm) appeared in both environments
  3. The process-default registry views did not match
  4. Do not create it as an ARM64 installation directory

On August 12, 2026, expanding %ProgramFiles(Arm)% on a Surface Pro 11 running Windows 11 ARM64 returned C:\Program Files (Arm). The directory itself did not exist. The practical answer is that this is not the installation directory for ARM64 applications.

Microsoft's Windows on Arm FAQ assigns C:\Program Files to x64, Arm64, and Arm64X applications; C:\Program Files (x86) to x86 applications; and says that C:\Program Files (Arm) “was used” for 32-bit Arm applications. It also says that 32-bit Arm is no longer being supported in future Windows versions. My machine showed the compatibility name still present in environment and registry data while the corresponding directory was absent.

Reading the same fields from ARM64 and x86 processes

The test machine was a Microsoft Surface Pro, 11th Edition with a Snapdragon X Elite X1E80100: 12 cores, 12 logical processors, and a 3.40 GHz reported clock. It had 33893933056 bytes of physical memory. The operating system was Microsoft Windows 11 Pro 25H2, build 26200.8875, on ARM64. The registry's ProductName value unexpectedly said Windows 10 Pro, so I did not use that legacy string as the authority for the visible product name.

The harness was native ARM64 Python 3.12.10. It launched two inbox Windows PowerShell executables by absolute path:

Target Executable PowerShell PE Machine IsWow64Process2
native ARM64 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 5.1.26100.8875 0xAA64 process 0x0000, native 0xAA64
emulated x86 C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe 5.1.26100.8875 0x014C process 0x014C, native 0xAA64

For a native process, IsWow64Process2 reports the process machine as 0x0000 by design; the executable's PE Machine was still 0xAA64. For the x86 case, both the executable file and the running process reported 0x014C, while the native machine was 0xAA64. That established the second case as x86 emulation on the same ARM64 operating system rather than a second native binary.

I ran the following command. Each process received two warm-up launches followed by nine measured rounds. The order alternated by round. Both commands fixed -NoLogo -NoProfile -NonInteractive, used the same encoded probe body, and were created by one native ARM64 parent without a custom environment block.

python scripts\program_files_arm_probe.py --warmups 2 --rounds 9 --output .bench\program-files-arm-2026-08-12.json

I did not aggregate execution time. This test asks whether the same query returns the same data, not which PowerShell starts faster. For each round, the script removed volatile timestamps and launch order from the immutable probe payload, serialized it as key-sorted UTF-8 JSON, and computed SHA-256. The aggregation was the number of unique hashes within each architecture, followed by a field-by-field comparison between the representative native and x86 payloads.

ProgramFiles(Arm) appeared in both environments

ProgramFiles and CommonProgramFiles changed with the process architecture. In contrast, ProgramFiles(Arm) and CommonProgramFiles(Arm) were present in both process environments.

Environment variable native ARM64 emulated x86
PROCESSOR_ARCHITECTURE ARM64 x86
PROCESSOR_ARCHITEW6432 not defined ARM64
ProgramFiles C:\Program Files C:\Program Files (x86)
ProgramFiles(x86) C:\Program Files (x86) C:\Program Files (x86)
ProgramFiles(Arm) C:\Program Files (Arm) C:\Program Files (Arm)
ProgramW6432 C:\Program Files C:\Program Files
CommonProgramFiles C:\Program Files\Common Files C:\Program Files (x86)\Common Files
CommonProgramFiles(x86) C:\Program Files (x86)\Common Files C:\Program Files (x86)\Common Files
CommonProgramFiles(Arm) C:\Program Files (Arm)\Common Files C:\Program Files (Arm)\Common Files

I initially expected an environment variable that resolves successfully to correspond to a directory. That expectation failed. Literal path checks from both processes produced the same results in all nine measured rounds:

Literal path Exists
C:\Program Files yes
C:\Program Files (x86) yes
C:\Program Files (Arm) no
C:\Program Files (Arm64) no
C:\Program Files (Arm)\Common Files no

A non-empty %ProgramFiles(Arm)% expansion therefore did not prove that its target existed. More importantly, the word Arm did not make it an ARM64 application directory. On this machine, normal ARM64 applications belonged under C:\Program Files.

The process-default registry views did not match

The probe also read HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion. The native ARM64 process's default view contained ProgramFilesDir (Arm) and CommonFilesDir (Arm), both pointing to absent paths. The emulated x86 process's default view did not contain those two values. That produced an apparent contradiction: the x86 environment had ProgramFiles(Arm), but the x86 process-default registry view lacked the similarly named value.

I did not turn that observation into a claim that Windows must generate the variable from a particular source. Both children came from the same native parent, so environment inheritance and WOW64 adjustments are part of the setup. Instead, the script opened the registry's Registry64 and Registry32 views explicitly from both processes and compared like with like.

The explicit Registry64 results matched exactly across both processes. That view contained ProgramFilesDir (Arm) and CommonFilesDir (Arm). The explicit Registry32 results also matched exactly across both processes, and that view did not contain either Arm value. Specifying the logical view removed the misleading process-default comparison.

Across the nine measured rounds, native ARM64 produced one canonical payload hash, 2ffe1d71ab4d452ed829ce94520d7f7904c6a2a4a46e4054e8b1d76c6d51203f. Emulated x86 also produced one, a65061feb727b492513efdb9c65e74c2304a2ea4f7bbfaed074a4185eb9345dc. The hashes should differ between architectures because architecture-specific fields differ. The validity checks were that all nine results within each side collapsed to one hash, literal path results matched across sides, and both explicit registry views matched across sides. I saw no fluctuation or non-reproducing field in this run.

Do not create it as an ARM64 installation directory

For the search question “What is Program Files (Arm)?”, the answer is: it is a compatibility path that was used for 32-bit Arm applications, not the modern ARM64 Program Files directory. On my Windows 11 ARM64 system on 2026-08-12, environment variables and 64-bit registry values remained, while the directory did not. Installers and scripts should not infer target architecture from this legacy folder name or hardcode it. Microsoft recommends using the appropriate Known Folder APIs for architecture-aware path discovery.

Microsoft documents the folder roles in the Windows on Arm FAQ. Code dealing with WOW64 paths and registry views also needs the rules in File System Redirector and Registry Redirector.

The earlier Program Files executable architecture census counted binaries under installed directories. I did not reuse those counts here. This experiment covered folder semantics, environment variables, registry views, and literal existence only. It is also separate from the System32 PE-header census; I did not measure general file-system redirection performance.

I did not test an x64 process, a real Arm32 process, a second PC, an older build, a clean Windows installation, directory creation by an installer, or the return values of Known Folder APIs. I also did not test whether 32-bit Arm programs still execute, and I cannot claim that these variables will remain in a future release. Nine stable rounds establish repeatability only for this one machine on build 26200.8875, not a universal property of every Windows on Arm installation.

Windows Architecture PowerShell
a
arm64lab — Independent publisher

Personal test notes from a Surface Pro 11th Edition with Snapdragon X Elite, used as a daily machine since May 2025. Results are based on direct measurements and do not represent any company or organization.