Program Files (Arm) は何?Windows ARM64実機では環境変数だけ残り、フォルダはなかった
この記事の見出し
2026年8月12日、Surface Pro 11のWindows 11 ARM64で%ProgramFiles(Arm)%を実際に展開するとC:\Program Files (Arm)になった。しかし、そのフォルダは存在しなかった。結論は単純で、ここはARM64アプリのインストール先ではない。
MicrosoftのWindows on Arm FAQでは、C:\Program Filesをx64、Arm64、Arm64X向け、C:\Program Files (x86)をx86向け、C:\Program Files (Arm)を過去の32-bit Armアプリ向けと説明している。公式の表現は「was used」であり、32-bit Armは将来のWindowsでサポートされなくなるという位置づけだ。手元の結果は、その古い互換名だけが環境変数とレジストリに残り、実フォルダは存在しない状態だった。
ARM64とx86の2プロセスから同じ項目を読んだ
検証機はMicrosoft Surface Pro, 11th Edition、Snapdragon X Elite X1E80100(12コア、12論理プロセッサ、3.40 GHz)、メモリ33893933056 bytes。OSはMicrosoft Windows 11 Pro 25H2、build 26200.8875、ARM64だ。レジストリのProductNameだけはWindows 10 Proを返したため、そこをOS名の根拠には使わなかった。これは途中で予想と違った点のひとつだった。
測定ハーネスはARM64ネイティブのPython 3.12.10。そこから次の2本を絶対パスで起動した。
| 対象 | 実行ファイル | 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 |
ネイティブプロセスでIsWow64Process2のprocess machineが0x0000になるのはAPIの仕様で、実行ファイル自体のPE Machineは0xAA64だった。x86側はファイルと実行中プロセスの両方が0x014C、native machineが0xAA64なので、ARM64上のx86エミュレーションとして比較できる。
コマンドは次の1本。各プロセスを2回ウォームアップしたあと9ラウンド測定し、起動順はラウンドごとに入れ替えた。-NoLogo -NoProfile -NonInteractiveを固定し、親から独自の環境ブロックは渡していない。
python scripts\program_files_arm_probe.py --warmups 2 --rounds 9 --output .bench\program-files-arm-2026-08-12.json
時間は集計していない。ここで知りたいのは起動性能ではなく、同じ問い合わせが毎回同じ値を返すかどうかだからだ。各ラウンドから時刻や順番を除いた不変JSONを作り、キー順を固定したUTF-8へSHA-256をかけた。同一アーキテクチャ内のunique hash数を集計し、さらに日英記事に載せる値は2プロセス間でフィールド単位に比較した。
ProgramFiles(Arm)は両方にあった
環境変数の結果は次のとおり。ProgramFilesとCommonProgramFilesはプロセスの実行アーキテクチャで変わったが、ProgramFiles(Arm)とCommonProgramFiles(Arm)は両方に残っている。
| 環境変数 | native ARM64 | emulated x86 |
|---|---|---|
PROCESSOR_ARCHITECTURE |
ARM64 |
x86 |
PROCESSOR_ARCHITEW6432 |
未定義 | 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 |
最初は、変数があるならフォルダもあるだろうと思っていた。ここは手元では外れている。literal pathを両プロセスで確認すると、次の5件は9ラウンドすべて同じ判定になった。
| literal path | 存在 |
|---|---|
C:\Program Files |
あり |
C:\Program Files (x86) |
あり |
C:\Program Files (Arm) |
なし |
C:\Program Files (Arm64) |
なし |
C:\Program Files (Arm)\Common Files |
なし |
%ProgramFiles(Arm)%が文字列を返すことは、保存先が実在する証拠にならない。ましてArmという名前を見て、ARM64アプリをそこへ入れる判断はできない。私の環境でのARM64アプリの通常の場所はC:\Program Filesになる。
defaultレジストリviewは一致しなかった
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersionも確認した。ARM64プロセスのdefault viewにはProgramFilesDir (Arm)とCommonFilesDir (Arm)があり、それぞれ存在しないパスを指す。一方、x86プロセスのdefault viewではこの2値を確認できない。環境変数には両方とも値があるのに、現在のdefaultレジストリviewだけを見るとx86側では見つからない。
ここで「x86ではArm変数がレジストリ以外から生成される」と断定するのはやめた。同じ親プロセスから起動しているため、環境ブロックの継承とWOW64の調整が混ざるからだ。代わりに、両プロセスからRegistry64とRegistry32を明示して同じvalue名を読んだ。
明示したRegistry64の結果は両プロセスで一致しており、ProgramFilesDir (Arm)とCommonFilesDir (Arm)が存在する。Registry32も両プロセスで一致するが、Armの2値は存在しない。process-default viewだけを並べる失敗を避け、同じ物理view同士で比較できる。
9ラウンドのcanonical JSONは、native ARM64が2ffe1d71ab4d452ed829ce94520d7f7904c6a2a4a46e4054e8b1d76c6d51203f、emulated x86がa65061feb727b492513efdb9c65e74c2304a2ea4f7bbfaed074a4185eb9345dcの各1種類だけだった。異なるアーキテクチャ同士のhashが違うのは想定どおりで、比較に使ったのは各側の9回が1種類へ収束したこと、literal path判定、明示したRegistry64、Registry32が両側で一致したことだ。今回は揺れも再現しない値も出なかった。
ARM64のインストール先として作らない
Program Files (Arm)という検索語に対する答えは、「32-bit Arm向けに使われていた互換パスで、ARM64向けではない」。2026-08-12の私のWindows 11 ARM64では変数と64-bitレジストリ値だけが残り、ディレクトリはなかった。インストーラーやスクリプトなら名前をハードコードせず、対象アーキテクチャとKnown Folder APIを使うほうが安全だ。
Microsoftの説明はWindows on Arm FAQにあり、WOW64のpathやregistry viewを扱う場合はFile System RedirectorとRegistry Redirectorも前提になる。
以前のProgram Files配下のEXEアーキテクチャ調査ではファイル本数を数えたが、今回は本数を使い回していない。対象はfolder名の意味、環境変数、レジストリview、実在確認だけだ。System32のPE調査とも違い、ファイルシステムredirectの一般性能は測っていない。
測っていないのはx64プロセス、実際のArm32プロセス、別PC、過去build、Windowsの新規インストール直後、アプリを入れたときのfolder生成、Known Folder APIの返値だ。32-bit Armの実行可否も試していないし、この変数が将来も残るとは断定できない。正直、9回一致したのはこの1台のbuild 26200.8875での再現性までで、Windows on Arm全体の普遍性ではない。