Skip to content

(#1803) Add native Windows on ARM (arm64) detection#3907

Open
dennisameling wants to merge 3 commits into
chocolatey:developfrom
dennisameling:windows-arm64-support
Open

(#1803) Add native Windows on ARM (arm64) detection#3907
dennisameling wants to merge 3 commits into
chocolatey:developfrom
dennisameling:windows-arm64-support

Conversation

@dennisameling

Copy link
Copy Markdown

Description Of Changes

Adds reliable native processor-architecture detection to Chocolatey CLI and removes the long-standing workaround that forced every Windows on ARM (arm64) host to be treated as 32-bit (x86).

  • Reliable native architecture detection (C#). New NativeProcessorArchitecture and IsArm64OperatingSystem members on the IEnvironment adapter determine the operating system's native architecture (x86 / x64 / arm64) through the Win32 IsWow64Process2 API. This is accurate even when choco.exe runs under emulation on Windows on ARM, where PROCESSOR_ARCHITECTURE and RuntimeInformation.OSArchitecture report the emulated architecture instead.
  • Removes the "force 32-bit on ARM64" workaround in Environment.Is64BitProcess and Get-OSArchitectureWidth. With Windows 11 x64 emulation, arm64 hosts now report 64-bit rather than being limited to x86.
  • Surfaces the native architecture to package scripts via a new OS_PROCESSOR_ARCHITECTURE environment variable and a new Get-OSArchitecture helper that returns x86, x64, or arm64.
  • CI. Adds native windows-11-arm build and test jobs to the GitHub Actions workflows, folded into a matrix alongside the existing x64 Windows jobs.

This is the foundational step (architecture detection + native CI). Package-author-facing arm64 asset selection (urlArm64 / checksumArm64 / fileArm64, tools\arm64 shimming) and native arm64 bundled tooling are intended as follow-up work toward the broader arm64 support tracked in #1803.

Note for reviewers: the two helper scripts this PR touches (Get-OSArchitecture.ps1, Get-OSArchitectureWidth.ps1) are unsigned, so the PowerShell signature-verification step will need them re-signed with the Chocolatey certificate. The stale signature block on Get-OSArchitectureWidth.ps1 has been removed rather than left invalid.

Motivation and Context

On Windows on ARM, Chocolatey previously selected the 32-bit (x86) variant of every package. That behaviour dates to a 2019 assumption (called out in the old Get-OSArchitectureWidth notes) that Windows on ARM would only ever provide an x86 emulator. That is no longer true: Windows 11 ships x64 emulation, and a growing number of applications publish native arm64 builds. As a result, arm64 users get slower x86-emulated software today, and some packages fail outright when they ship only x64 (or arm64) assets.

The previous detection was also unreliable. Because choco.exe is a .NET Framework process that itself runs under emulation on arm64, its in-process PROCESSOR_ARCHITECTURE reports AMD64/x86 and never ARM64. IsWow64Process2 is the supported Win32 API that reports the true native architecture regardless of emulation.

GitHub Actions now provides free windows-11-arm runners for public repositories, which makes it possible to build and unit-test choco natively on Windows on ARM.

Testing

  1. Updated the Environment adapter unit specs (EnvironmentSpecs) to cover the new NativeProcessorArchitecture / IsArm64OperatingSystem members and the revised Is64BitProcess behaviour, then ran the unit-test suite.
  2. Built and unit-tested through the GitHub Actions workflows on both the x64 and arm64 Windows runners. The solution compiles with 0 Error(s) and the unit suite passes (1190 passed, 2 pre-existing skips) on both architectures.

Operating Systems Testing

  • Windows 11 (x64) — GitHub Actions windows-latest
  • Windows 11 on ARM (arm64) — GitHub Actions windows-11-arm

Change Types Made

  • Bug fix (non-breaking change).
  • Feature / Enhancement (non-breaking change).
  • Breaking change (fix or feature that could cause existing functionality to change).
  • Documentation changes.
  • PowerShell code changes.

On Windows 11 on ARM, package architecture selection changes from x86 to x64, so this is flagged as a behaviour change.

Change Checklist

  • Requires a change to the documentation.
  • Documentation has been updated.
  • Tests to cover my changes, have been added.
  • All new and existing tests passed?
  • PowerShell code changes: PowerShell v3 compatibility checked?
  • All items are complete on the Definition of Done.

The new Get-OSArchitecture helper and OS_PROCESSOR_ARCHITECTURE variable warrant documentation in the docs repository. The helper is PowerShell v2-compatible (it uses Get-WmiObject rather than Get-CimInstance).

Related Issue

Relates to #1803
Fixes #2172

choco treated every ARM64 host as 32-bit (x86). When that code was
written, Windows on ARM only shipped an x86 emulator, but Windows 11 now
provides x64 emulation and many applications ship native arm64 builds, so
the assumption is obsolete and forces emulated x86 packages onto arm64
users.

Detect the operating system's native architecture reliably through the
IsWow64Process2 Win32 API, which is correct even when choco.exe runs
under emulation (PROCESSOR_ARCHITECTURE and
RuntimeInformation.OSArchitecture report the emulated architecture). It
is exposed on the IEnvironment adapter as NativeProcessorArchitecture and
IsArm64OperatingSystem.

Remove the workarounds that forced ARM64 to 32-bit in
Environment.Is64BitProcess and Get-OSArchitectureWidth so arm64 hosts use
x64 emulation. Surface the native architecture to package scripts via a
new OS_PROCESSOR_ARCHITECTURE environment variable and a new
Get-OSArchitecture helper returning x86, x64 or arm64.

Add native windows-11-arm jobs to the build and test workflows (as a
matrix with the existing x64 Windows jobs) so choco is built and
unit-tested on real Windows on ARM hardware.
@CLAassistant

CLAassistant commented Jun 2, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@st3phhays

Copy link
Copy Markdown
Member

Hey @dennisameling thank you for taking the time to put this together! We’ll want to carefully review and validate the changes here. I’m not able to give an ETA on review at the moment, but we appreciate your patience while we evaluate it.

dennisameling and others added 2 commits June 7, 2026 18:36
Add <supportedArchitectures>amd64 arm64</supportedArchitectures> to
choco.exe.manifest so the AnyCPU CLI runs natively as ARM64 on Windows 11
24H2+ rather than x64-emulated (the .NET Framework AnyCPU default on Windows
on ARM). Older hosts ignore the element and fall back to x64 emulation.

Also correct comments that assumed the CLI always runs emulated on ARM.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…64 constant

Add Pester tests for Get-OSArchitecture and Get-OSArchitectureWidth that
validate sane, OS-consistent values on both x64 and Windows on ARM (arm64)
runners.

Mark ApplicationParameters.Environment.Arm64ProcessorArchitecture obsolete: it
is no longer referenced now that ARM64 detection goes through IEnvironment
(NativeProcessorArchitecture / IsArm64OperatingSystem).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dennisameling

Copy link
Copy Markdown
Author

I just ran some tests and can confirm this is working as expected on arm64 Windows host. Combined with chocolatey-community/chocolatey-packages#2796, here's a successful installation of Firefox arm64 (notice win64-aarch64 in the URL):

> choco install firefox -s "C:\repos\chocolatey-packages\automatic\firefox" -f -y --allow-unofficial
Chocolatey v2.8.0-windowsarm-20260607-e3472f8a

Chocolatey is not an official build (bypassed with --allow-unofficial).
 If you are seeing this message and it is not expected, your system may
 now be in a bad state. Only official builds are to be trusted.

Installing the following packages:
firefox
By installing, you accept licenses for the packages.
Firefox v151.0.3 already installed. Forcing reinstall of version '151.0.3'.
 Please use upgrade if you meant to upgrade to a new version.
Downloading package from source 'C:\repos\chocolatey-packages\automatic\firefox'

Firefox v151.0.3 (forced)
Firefox package files install completed. Performing other installation steps.
Using locale 'en-US'...
Downloading Firefox
  from 'https://download.mozilla.org/?product=firefox-151.0.3-ssl&os=win64-aarch64&lang=en-US'
Progress: 100% - Completed download of C:\Users\dennisameling\AppData\Local\Temp\chocolatey\Firefox\151.0.3\Firefox Setup 151.0.3.exe (77.44 MB).
Download of Firefox Setup 151.0.3.exe (77.44 MB) completed.
Hashes match.
Installing Firefox...
Firefox has been installed.
WARNING: No registry key found based on  'Mozilla Firefox'
  Firefox may be able to be automatically uninstalled.
 The install of Firefox was successful.
  Deployed to 'C:\Program Files\Mozilla Firefox'

Chocolatey installed 1/1 packages.
 See the log for details (C:\repos\choco\src\chocolatey.console\bin\Release\net48\logs\chocolatey.log).

In Task Manager I could see that choco.exe now runs as a native arm64 process:

afbeelding

I have some questions for the maintainers:

  • Chocolatey has a --x86, --forcex86 flag. It looks like no all community packages respect that flag currently. When arm64 support is added, should a --forcex64 flag also be added if the user wants to force install a x64 package on an arm64 machine? Or should Chocolatey always detect the machine/host architecture and use that? So on an arm64 device it would always download arm64 packages unless a package has fallback logic to install a x64 app if no arm64 version is available for that specific package.
  • This repo currently has x86 versions of 7z.exe, checksum.exe and shimgen.exe checked into it. Those will run fine under emulation in Windows arm64 (it supports both x86 and x64 emulation), just with lower performance. I'm not sure how often these are used - 7-Zip definitely has native arm64 binaries available.

Some other notes:

Native ARM64 execution + heads-up for package authors

choco.exe is an AnyCPU .NET Framework assembly, which by Windows design runs as x64-emulated on Windows on ARM (the PE is stamped i386; the CLR picks the run architecture at load time). To make the CLI run natively as ARM64, this adds a <supportedArchitectures>amd64 arm64</supportedArchitectures> element to choco.exe.manifest.

  • Takes effect on Windows 11, version 24H2 and later; on older hosts it is ignored and the CLI continues to run x64-emulated (safe fallback).
  • Verified with GetProcessInformation(ProcessMachineTypeInfo) (the authoritative API Task Manager uses) that a rebuilt CLI runs as ARM64, including the install path (in-process PowerShell host + NuGet) with no BadImageFormatException.
  • Note: IsWow64Process2 alone cannot confirm this — on ARM64 it returns processMachine = UNKNOWN for both native-ARM64 and x64-emulated processes, because x64 emulation is not classic WOW64.

⚠️ Behavior change for package authors

When choco runs natively as ARM64, $env:PROCESSOR_ARCHITECTURE is now ARM64 (it was AMD64 under x64 emulation). Packages that branch on $env:PROCESSOR_ARCHITECTURE -eq 'AMD64' may now take a different code path. Recommended:

  • For bitness decisions, use Get-OSArchitectureWidth — it returns 64 whether choco runs natively as ARM64 or under x64 emulation.
  • When a package ships native arm64 binaries, use the new Get-OSArchitecture (or the $env:OS_PROCESSOR_ARCHITECTURE value: x86 / x64 / arm64) to decide what to install.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ARM64 now has x64 emulation

3 participants