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) https://learn.microsoft.com/en-us/windows/arm/arm64x-pe.

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: https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details

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

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.