ARM64_Lab

Program Files (Arm) は何?Windows ARM64実機では環境変数だけ残り、フォルダはなかった

この記事の見出し
  1. ARM64とx86の2プロセスから同じ項目を読んだ
  2. ProgramFiles(Arm)は両方にあった
  3. defaultレジストリviewは一致しなかった
  4. 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)は両方にあった

環境変数の結果は次のとおり。ProgramFilesCommonProgramFilesはプロセスの実行アーキテクチャで変わったが、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の調整が混ざるからだ。代わりに、両プロセスからRegistry64Registry32を明示して同じ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判定、明示したRegistry64Registry32が両側で一致したことだ。今回は揺れも再現しない値も出なかった。

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 RedirectorRegistry 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全体の普遍性ではない。

a
arm64lab — 個人運営

Surface Pro 11th Edition(Snapdragon X Elite)を2025年5月から常用機にしている個人の記録です。ARM64 版 Windows で詰まったところと、その場で測った値をそのまま書き残しています。特定の企業・団体とは関係がなく、いかなる組織を代表する見解でもありません。