Case 01 / 17 · WireGuard switch for Windows · 2026
WgSwitch
A lightweight switch for a personal WireGuard VPN: one button turns the tunnel on, and the app tells the truth about whether the server answers — not “the service is running” but a ping inside the tunnel. Several servers at once, a tray icon coloured by state, notifications and auto-reconnect, a wizard that creates keys and the config itself, and an encrypted backup of the keys. No third-party libraries; the lite build is 0.6 MB.
https://github.com/lolkekxa/WgSwitch
- Development time: 2 days
- Lines of code: 4,000+
- Tests: 42
- Lite build: 0.6 MB
Challenge
The official WireGuard client for Windows shows “Active” even when the server has long been down; turning on a second server turns off the first by default; a new tunnel means generating keys and assembling a config by hand. And once SSH and server panels are locked behind the VPN, lost keys mean a trip to the host’s web console.
Solution
WPF on .NET 8 without a single NuGet package: the window, tray and animations in the studio style; tunnels are driven by the official wireguard.exe, Windows services are queried directly through the Win32 API, and status is a ping inside the tunnel plus the handshake from wg.exe. Polling is adaptive: in the tray with tunnels off it runs every 15 seconds and starts no processes. Keys come from wg.exe, configs live in a folder only administrators can open, and the backup is encrypted with AES-256-GCM using a PBKDF2 key derived from the password. 42 tests and a GitHub Actions build: a dark-themed Inno Setup installer, portable and lite builds, checksums in the release. The app ships with a server guide: firewall, SSH and panels reachable only through the tunnel, Docker bypassing ufw.
Highlights
0 NuGet packages, lite is 0.6 MB · A ping inside the tunnel, not “service running” · Several servers at once · Keys in an encrypted .wgsb
What was built
- One button: a thin ring and an icon in the state colour — off, connecting, connected, no response
- An honest status: a ping to the server inside the tunnel, handshake and traffic from wg.exe
- Several servers: chips above the button, each with its own subnet, can be on at the same time
- A tray icon coloured by state with a per-server menu; the window opens by the clock and hides to the tray
- Notifications when the connection drops and when it comes back, auto-reconnect after 2 minutes of silence
- A first-run wizard: keys via wg.exe, the config in a locked folder, a ready [Peer] block for the server
- Rename, delete, “all internet through VPN” mode and auto-connect — per server
- An encrypted backup of servers and keys: AES-256-GCM and PBKDF2, restored right from the wizard on a new computer
- Autostart through Task Scheduler with highest privileges — no UAC prompt at sign-in
- Adaptive polling: every 15 seconds when idle with no processes started, memory returned to the system when the window closes
- A dark-themed installer that installs the official WireGuard on request; portable and lite builds alongside
- 42 tests and a GitHub Actions build: a release from a tag with notes from CHANGELOG and SHA-256
- A server guide: firewall, SSH and panels only through the tunnel, Docker bypassing ufw, troubleshooting
Stages
- Switch (half a day) — The studio-style window, the tunnel service via wireguard.exe, status from SCM and ping, a tray coloured by state
- Servers and wizard (half a day) — Keys via wg.exe, the config in a locked folder, several servers with different subnets
- Reliability (half a day) — A password-protected backup, notifications, auto-reconnect, “all internet” mode
- Delivery (half a day) — Tests, the dark installer, GitHub Actions releases, the server guide and troubleshooting
Next project: Northstar