Identify CPU architecture
On Windows, to identify your CPU architecture, the standard way is to read the PROCESSOR_ARCHITECTURE environment variable.
For an x64 binary, it will always be set to AMD64.
For an arm64 binary, it will always be set to ARM64.
Even if you can set the variable manually, its value won’t be propagated in children processes, but set according to child binary architecture.
ARM64X
There is one specific case: ARM64X binaries, which can be seen as “universal” binaries (containing arm64ec and arm64 code) Arm64X PE Files.
In this case, the PROCESSOR_ARCHITECTURE is set as the architecture of the parent process.
If the parent is x64, it will be set to AMD64.
If the parent is arm64, it will be set to AMD64.
If the parent is arm64x, grandparent architecture is used.
This is not documented anywhere, but at least someone else observed it:https://github.com/flutter/flutter/pull/121999#issuecomment-1459603624
Edit: Some documentation mentions it: WOW64 Implementation Details - Win32 apps
Identify binary architecture
dumpbin /headers C:/path/to/binary.exe | grep machine
Note: dumpbin command is accessible from VS prompt.
$ dumpbin /headers c:/wenv/arm64/msys2/msys64/usr/bin/bash.exe | grep machine
8664 machine (x64)
$ dumpbin /headers c:/Windows/System32/WindowsPowerShell/v1.0//powershell.exe | grep machine
AA64 machine (ARM64) (ARM64X)
$ dumpbin /headers C:/Windows/system32/cmd.exe | grep machine
AA64 machine (ARM64) (ARM64X)
$ dumpbin /headers C:/Windows/system32/calc.exe | grep machine
AA64 machine (ARM64)
Some shell fun
As you can notice in above example, cmd.exe
and powershell.exe
are both arm64x binaries. Thus, they adopt the same PROCESSOR_ARCHITECTURE than their parent.
This can create subtle issues, if you use a script trying to identify architecture, that will change depending on who launched it. Not… funny. This takes us too…
Force CPU architecture
If you need a force a given CPU architecture, for a batch or powershell script, you can use:
From Windows 22H2:
start /machine x86|amd64|arm|arm64
start
Before:
You can use any process to launch your command. Python might be a good candidate:python3 -c "import subprocess; subprocess.call('cmd.exe')"
And execute python x86, x64 or arm64 depending on your need.