Yes, you can run Windows on a Raspberry Pi. Specifically, you can run full Windows 11 ARM64 on the Raspberry Pi 5 (8GB variant) and the Raspberry Pi 4 (8GB variant). However, this is not a simple plug-and-play SD card flash like Raspberry Pi OS. It requires custom UEFI firmware to bridge the ARM silicon to the Windows HAL (Hardware Abstraction Layer), and it demands NVMe storage to prevent the OS from choking on background telemetry.

While hobbyists often ask if they can use this for a daily desktop replacement, the real power of this setup lies in embedded edge computing. Running Windows 11 IoT Enterprise or standard ARM64 builds allows you to deploy .NET 8 applications, interface directly with GPIO via the System.Device.Gpio library, and integrate seamlessly into Active Directory or Azure IoT environments.

Project Difficulty: Intermediate to Advanced
Estimated Time: 2 hours (Flashing) + 1 hour (Hardware/Code)
Target Board: Raspberry Pi 5 (8GB RAM)

Hardware Spec Sheet & Parts List

Do not attempt this build with a Raspberry Pi 3 or a 2GB/4GB Pi 4. Windows 11 ARM64 idles at roughly 2.5GB of RAM and heavily utilizes swap space. Furthermore, SD cards will fail under Windows 11's random 4K write patterns. You must boot from NVMe.

Component Exact Variant / Specification Why This Specific Part?
Compute Module Raspberry Pi 5 (8GB RAM) PCIe Gen 2.0 interface for NVMe; BCM2712 SoC handles Win11 ARM64 instructions natively.
Storage Samsung 980 256GB NVMe M.2 (2230 or 2242) Avoid QLC drives like the Crucial P3. Windows indexing requires high sustained TLC random writes.
NVMe HAT Pimoroni NVMe Base or Official Pi 5 M.2 HAT+ Provides the PCIe ribbon cable and 3.3V power regulation required by the Pi 5.
Power Supply Official Raspberry Pi 27W USB-C PD Supply Windows boot spikes can draw 22W+. Third-party chargers often drop voltage, causing brownouts.
Cooling Official Active Cooler The BCM2712 hits 85°C in seconds under Windows boot loads without active forced air.
Peripherals Standard Tactile Switch, 330Ω Resistor, 5mm LED For the GPIO validation circuit.

Flashing UEFI Firmware and Windows 11 ARM64

The Raspberry Pi does not have a standard BIOS. To install Windows, we must flash an EDK2 UEFI firmware to an SD card, boot from it, and then install Windows onto the NVMe drive via a USB installer.

Pro-Tip: The Windows on Raspberry (WoR) project maintains the most reliable UEFI builds and deployment tools for ARM64 SBCs. Always check their compatibility matrix before downloading Insider Preview builds, as Microsoft occasionally breaks the BCM2712 ACPI tables in Canary channel releases.
  1. Prepare the UEFI SD Card: Download the latest Pi 5 UEFI firmware from the pftf/RPi5 GitHub repository. Extract the contents onto a FAT32-formatted 16GB SD card.
  2. Create the Windows Installer: Use the WoR Flasher tool or Rufus to write a Windows 11 ARM64 ISO to a 32GB USB 3.0 flash drive.
  3. Configure Boot Order: Insert the SD card and USB drive into the Pi 5. Power on. Press ESC repeatedly to enter the UEFI BIOS menu. Navigate to Boot Maintenance Manager and ensure the USB drive is prioritized, but set the PCIe NVMe drive as the primary boot target for post-installation.
  4. Install Windows: Boot from the USB. When prompted for a driver, you may need to load the PCIe storage driver included in the UEFI package if the NVMe drive isn't visible. Format the NVMe drive and proceed with the installation.
  5. Post-Install Drivers: Once on the Windows desktop, run the WoR driver installation script (usually provided on the UEFI SD card's boot partition) to install the Broadcom SDIO, Bluetooth, and GPIO ACPI drivers.

GPIO Pin Mapping & C# Embedded Code

With Windows 11 ARM64 running, we can write native .NET 8 applications that interact with the physical pins. The code below targets the Raspberry Pi 5 (8GB) and uses the System.Device.Gpio NuGet package to read a button on GPIO 27 and toggle an LED on GPIO 17.

Pin Mapping Table

Component BCM GPIO Pin Physical Pin (Header) Wiring Notes
LED Anode (+) GPIO 17 Pin 11 Connect through a 330Ω resistor.
LED Cathode (-) GND Pin 9 Common ground.
Button Output GPIO 27 Pin 13 Use internal Pull-Up resistor in code.
Button Input GND Pin 14 Pulls GPIO 27 low when pressed.

Complete C# Console Application

Create a new .NET 8 Console App and add the NuGet package: dotnet add package System.Device.Gpio.

using System;
using System.Device.Gpio;
using System.Threading;

namespace Pi5WindowsEdgeNode
{
    class Program
    {
        // BCM Pin Definitions for Raspberry Pi 5
        const int LedPin = 17;
        const int ButtonPin = 27;

        static void Main(string[] args)
        {
            Console.WriteLine("Initializing Windows 11 ARM64 GPIO Controller...");
            
            // Initialize with PinNumberingScheme.Logical (BCM)
            using GpioController controller = new GpioController(PinNumberingScheme.Logical);
            
            try
            {
                controller.OpenPin(LedPin, PinMode.Output);
                // Use internal pull-up so we don't need an external resistor for the button
                controller.OpenPin(ButtonPin, PinMode.InputPullUp);
                
                Console.WriteLine("Pins opened successfully. Press the button to toggle the LED. Ctrl+C to exit.");
                
                bool ledState = false;
                
                // Register an event handler for button presses (falling edge = pressed to ground)
                controller.RegisterCallbackForPinValueChangedEvent(
                    ButtonPin, 
                    PinEventTypes.Falling, 
                    (sender, pinEvent) =>
                    {
                        ledState = !ledState;
                        controller.Write(LedPin, ledState ? PinValue.High : PinValue.Low);
                        Console.WriteLine($"Button pressed! LED state: {(ledState ? "ON" : "OFF")}");
                    });

                // Keep the application running
                var cts = new CancellationTokenSource();
                Console.CancelKeyPress += (s, e) =>
                {
                    e.Cancel = true;
                    cts.Cancel();
                };

                try
                {
                    Task.Delay(Timeout.Infinite, cts.Token).Wait();
                }
                catch (AggregateException) { /* Expected on Ctrl+C */ }
            }
            catch (PlatformNotSupportedException ex)
            {
                Console.WriteLine($"FATAL: GPIO not supported on this OS/Architecture. {ex.Message}");
                Console.WriteLine("Ensure you are running the ARM64 build of .NET and the WoR GPIO drivers are installed.");
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine($"FATAL: Access Denied to GPIO pins. {ex.Message}");
                Console.WriteLine("Run the terminal as Administrator or check UEFI ACPI GPIO binding.");
            }
            finally
            {
                if (controller.IsPinOpen(LedPin)) controller.ClosePin(LedPin);
                if (controller.IsPinOpen(ButtonPin)) controller.ClosePin(ButtonPin);
                Console.WriteLine("GPIO pins safely closed.");
            }
        }
    }
}

Debugging: First 3 Things to Check When It Fails

Running Windows on ARM silicon via a reverse-engineered UEFI layer introduces unique failure modes. If your C# deployment fails or the Pi crashes, check these three specific vectors first.

1. The "System.PlatformNotSupportedException" Error

Exact Error String: System.PlatformNotSupportedException: 'GPIO operations are not supported on this platform.'

Root Cause: You compiled your .NET app for win-x64 instead of win-arm64, or you are missing the Broadcom GPIO ACPI driver. Windows translates x86/x64 apps via emulation, but the emulation layer cannot pass hardware interrupts to the GPIO controller.

Fix: Publish your app specifically for ARM64: dotnet publish -r win-arm64 -c Release. Verify in Device Manager that the "Broadcom GPIO Controller" is present and has no yellow warning triangle.

2. The "0x80070005 Access Denied" on Pin Open

Exact Error String: System.UnauthorizedAccessException: 'Access to the path 'GPIO17' is denied.' (Error code 0x80070005)

Root Cause: Unlike Linux where you add a user to the gpio group, Windows 11 requires the application to have Administrator privileges to map physical memory addresses for the BCM2712 SoC, or the UEFI firmware failed to hand off the GPIO memory region to the OS.

Fix: Right-click your terminal or compiled .exe and select "Run as Administrator". If it still fails, reboot into the UEFI BIOS (press ESC at boot), navigate to Device Manager, and ensure the "Raspberry Pi GPIO" ACPI device is explicitly enabled.

3. System Freezes or NVMe Disconnects Under Load

Symptom: The system hard-locks when compiling code or running Windows Update, followed by a reboot and a missing C: drive in UEFI.

Root Cause: The Raspberry Pi 5's PCIe Gen 2.0 controller is highly sensitive to ASPM (Active State Power Management) link states, which Windows 11 aggressively enables to save power. This causes the NVMe drive to drop off the bus.

Fix: Open an elevated Command Prompt and disable PCIe ASPM globally: powercfg /setacvalueindex scheme_current sub_pciexpress aspm 0 followed by powercfg /setactive scheme_current.

FAQ: Running Windows on Raspberry Pi Hardware

Can you run Windows on a Raspberry Pi 4 or only the Pi 5?

You can run Windows 11 ARM64 on the Raspberry Pi 4 (specifically the 4GB and 8GB models), but the experience is noticeably degraded compared to the Pi 5. The Pi 4 lacks a native PCIe bus, forcing you to boot from a USB 3.0 SSD, which introduces higher latency. Furthermore, the Pi 4's BCM2711 SoC struggles with Windows 11's background Defender scans and telemetry, often resulting in 100% CPU usage for the first 20 minutes of boot. For any serious embedded edge node in 2026, the Pi 5 is the mandatory baseline.

Can you run Windows on a Raspberry Pi for gaming or daily desktop use?

Technically yes, practically no. While the WoR project enables GPU acceleration via the Microsoft Basic Display Adapter (and experimental Vulkan drivers), you are limited to ARM64-native Windows games or x86 emulation. The emulation layer takes a massive performance hit, turning a game that would run at 60 FPS on a standard Intel N100 into a 15 FPS slideshow. Treat this platform as a headless edge server, a digital signage kiosk, or an industrial IoT gateway, not a gaming rig.

How do I extend this build to read I2C sensors on Windows ARM64?

To simplify and extend this build for I2C sensors (like a BME280 temperature/humidity sensor), you use the System.Device.I2c NuGet package. The I2C1 bus on the Pi 5 maps to physical pins 3 (SDA) and 5 (SCL). You instantiate an I2cDevice using I2cConnectionSettings(1, 0x76). Ensure you enable the I2C ACPI overlay in the UEFI configuration file (config.txt on the UEFI boot partition) by adding dtparam=i2c_arm=on before flashing the firmware.

What is the difference between Windows 11 ARM and Windows 10 IoT Core?

Windows 10 IoT Core is a dead, deprecated platform that Microsoft officially retired. It was a stripped-down, single-app kiosk OS that lacked the full Win32 API. Windows 11 ARM64 (whether standard Pro or IoT Enterprise LTSC) is a full, desktop-class operating system. It supports multi-threading, full .NET 8, Docker (via Windows Containers), and standard Win32 GUI applications. For modern embedded projects, Windows 11 IoT Enterprise LTSC is the correct choice, as it strips out the consumer bloatware (Candy Crush, Xbox services) and locks the OS version for 10 years of edge deployment stability.