pywinhello
Automate Windows Hello PIN entry via USB HID keyboard (Raspberry Pi Pico).
Windows Hello's Credential Dialog is protected by UIPI — no software input method
(SendInput, pyautogui, pywinauto) can type into it. pywinhello uses a Raspberry Pi
Pico as a USB HID keyboard to bypass this restriction and enter PINs automatically.
Features
- Process-aware: identifies which app triggered Windows Hello, enters the correct PIN
- Two-pass detection: handles both PIN mode and fingerprint mode automatically
- Progressive API: from raw HID keyboard to full daemon monitor
- Zero polling: uses WinEvent hooks for instant dialog detection
- Automated Pico setup: flashes CircuitPython, downloads libraries, installs firmware
Install
pip install pywinhello
Hardware
Any Raspberry Pi Pico variant (Pico, Pico W, Pico 2, Pico 2 W) — ~$4.
Automated Setup
# Hold BOOTSEL on Pico, plug in USB, then:
pywinhello setup-pico
This handles everything: flashing CircuitPython, downloading adafruit_hid, and installing the HID bridge firmware.
Verify
pywinhello ping
# PONG from COM8
Quick Start
from pywinhello import enter_pin
# One-shot: enter PIN when dialog appears
event = enter_pin("1234")
print(event.dialog_dismissed) # True if PIN was accepted
Process-aware daemon
Create config.yaml:
apps:
- exe: MarketSpeed2.exe
pin: "1234"
- exe: chrome.exe
pin: "5678"
from pywinhello import HelloMonitor, load_config
config = load_config("config.yaml")
monitor = HelloMonitor(config)
monitor.serve(on_event=lambda e: print(e))
CLI
# Run monitor daemon
pywinhello serve -c config.yaml
# Ping Pico
pywinhello ping
# Set up Pico (flash + firmware)
pywinhello setup-pico
Architecture
Host (Python) Pico (CircuitPython) Windows
┌──────────┐ serial ┌──────────┐ USB HID ┌──────────┐
│ pywinhello│─────────→│ code.py │───────────→│ Credential│
│ │ TYPE:1234 │ keyboard │ keystrokes │ Dialog │
│ │←─────────│ │ │ │
│ │ OK │ │ │ │
└──────────┘ └──────────┘ └──────────┘
Progressive API
serve() Daemon — handles all dialogs automatically
└── handle_next() One-shot — wait for next dialog
└── enter_pin() Immediate — type PIN into current dialog
└── HIDKeyboard Raw — serial HID bridge
How it works
- Dialog detection —
SetWinEventHook(EVENT_OBJECT_CREATE)detectsCredential Dialog Xaml Hostinstantly - Process identification —
GetWindow(GW_OWNER)traces the dialog to the requesting process - Focus —
AttachThreadInput+SetForegroundWindowbrings the dialog to focus - Two-pass entry — Types PIN directly; if dialog persists, sends ESCAPE to navigate from fingerprint to PIN mode, then retries
- HID bypass — Physical keyboard input from the Pico bypasses UIPI restrictions
License
MIT
Metadata
Release files for pywinhello 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pywinhello-0.2.0.tar.gz | 86.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pywinhello-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 110.1 kB
Release files / pywinhello-0.2.0.tar.gz
| Download URL | pywinhello-0.2.0.tar.gz |
|---|---|
| Size | 86.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
483b6a1f7e7f4c7f31b2a98d2193b8352aa22588d48e86a7661be0a6bd01b93d
|
|
BLAKE2b-256 checksum How to use checksums |
fd6a7dab5c073a9df766b7bc57fbc01938cff6c1d6970d47fe25911669a95d0e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / pywinhello-0.2.0-py3-none-any.whl
| Download URL | pywinhello-0.2.0-py3-none-any.whl |
|---|---|
| Size | 23.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
27e8acd95ca9f7faca49861535b25ff09304d9739e20af08d07dadaa81d7d4c9
|
|
BLAKE2b-256 checksum How to use checksums |
dcf2fff36d4127f870ad280d08e814c7c5dc2dbb0fbc76012ef24901db6cd171
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for pywinhello 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.