ScreenBridge is a Windows-only tray app for sending a screenshot from one PC to another PC on the same LAN. Press Ctrl+Alt+PrintScreen on the sending PC, and the selected paired receiver copies the screenshot directly to its clipboard.
Received screenshots are also saved to local history, can show a Windows notification, and can optionally auto-open in a built-in preview window.
- Windows 10 or Windows 11
- .NET 8 SDK for building
- Both PCs must be on the same local subnet
- Windows Firewall must allow the app to receive UDP discovery and TCP transfers when prompted
dotnet build ScreenBridge.sln -m:1 -p:RestoreIgnoreFailedSources=trueThe -m:1 flag serializes the solution build. Individual project builds also work:
dotnet build src\ScreenBridge.App\ScreenBridge.App.csproj -p:RestoreIgnoreFailedSources=true
dotnet run --project tests\ScreenBridge.Tests\ScreenBridge.Tests.csproj -p:RestoreIgnoreFailedSources=true
dotnet run --project tests\ScreenBridge.App.Tests\ScreenBridge.App.Tests.csproj -p:RestoreIgnoreFailedSources=trueThe Core test executable covers protocol, settings ownership, migration, concurrent changes, and receive history failures. The app test executable checks actual Windows shortcut registration and rollback using hidden windows and isolated temporary settings. It briefly registers Ctrl+Alt+Shift+F22 and Ctrl+Alt+Shift+F23, then releases them.
Build the app once on the development PC, then copy the zip to the other PC. The other PC does not need the .NET SDK or source code.
.\scripts\publish-portable.ps1If you are using a portable SDK path:
.\scripts\publish-portable.ps1 -Dotnet D:\tmp\dotnet-sdk-8\dotnet.exeThe package is created at:
artifacts\ScreenBridge-win-x64.zip
Extract that zip on each Windows PC and run ScreenBridge.App.exe.
dotnet run --project src\ScreenBridge.App\ScreenBridge.App.csprojRun the app on both PCs. It appears as a tray icon and does not create a normal main window.
The default send shortcut is Ctrl+Alt+PrintScreen. To change it, right-click the tray icon and choose Change send shortcut....
To send only part of the screen, right-click the tray icon and choose Select send area..., then drag a rectangle and press Enter. While an area is configured, the send shortcut sends that cropped region instead of the active monitor. Use Clear send area to return to full active-monitor screenshots.
To use the shortcut to screenshot the selected paired PC instead, right-click the tray icon and enable Shortcut screenshots selected receiver. The selected receiver captures its own configured send area, then sends that screenshot back to your clipboard and history.
- Start ScreenBridge on both PCs.
- On the receiving PC, right-click the tray icon and choose
Pair device...; note the local pairing code. - On the sending PC, right-click the tray icon and choose
Pair device.... - Select the receiver from the discovered devices list, enter the receiver's pairing code, and click
Pair. - Press
Ctrl+Alt+PrintScreenon the sender. The receiver clipboard will contain the screenshot.
Open historyshows received screenshots newest-first.Auto-open received printstoggles whether incoming screenshots open in the built-in preview window.Auto-open full screenopens auto-opened previews maximized.- Incoming screenshots are saved under
%APPDATA%\ScreenBridge\History. - ScreenBridge keeps the newest 100 received screenshots by default.
- Windows toast notifications are enabled by default. The app creates a Start Menu shortcut named
ScreenBridgeso Windows can associate notifications with the app.
- Pairing secrets are stored in
%APPDATA%\ScreenBridge\settings.jsonprotected with Windows DPAPI. - Receive history metadata and feature toggles are stored in the same settings file.
- Discovery uses UDP port
37645. - Screenshot transfer uses TCP port
37646unless the app is configured otherwise in settings. - v1 supports one selected receiver at a time.
SettingsStore owns settings. Callers read independent snapshots and request serialized changes; a failed save retains the previous settings in memory and on disk. Each save writes and flushes a temporary file in the settings directory, then replaces the destination with a same-directory rename.
The settings document now has a schemaVersion and a nested settings object. Existing unversioned settings are migrated automatically, preserving device identity, paired-device secrets, preferences, and history metadata. The original file is kept as settings.json.legacy.bak; if that name already contains a different original, migration creates an additional settings.json.legacy.<id>.bak. Unknown format versions or unreadable settings stop startup with an error and preserve the file.
History pruning and deletion save metadata before removing PNG files. A file that cannot be removed stays in a persisted cleanup queue and is retried on startup or a later history operation; the app shows a warning. Shortcut changes restore the previous Windows registration after a settings save failure. If restoration fails, the shortcut is disabled and the app reports the error.
The ownership contract assumes one SettingsStore instance for the running app. It does not coordinate multiple app processes writing the same settings file.
See GLOSSARY.md for domain terms and docs/adr/0001-settings-ownership.md for the design decision.
A received screenshot is acknowledged after it is saved to history and copied to the clipboard. If clipboard copying fails, the sender is told that history was saved but clipboard delivery failed. Notifications and automatic preview run separately; their failures warn without rejecting the receipt. Up to 16 presentation tasks are retained; a full optional queue skips presentation with a warning. Preview uses the received bytes even if the history file is later removed.
The transfer module owns up to 16 active connections with 20-second request deadlines. It reports malformed requests and callback failures, and shutdown cancels and waits for active work. The app also stops selected receiver actions, pairing, discovery, and optional receipt presentation before normal exit.
Signed requests reserve a nonce before executing. Repeated messages from the same paired device and request kind are rejected for their timestamp window. The bounded replay cache is held in memory, so restarting the receiver clears it. New user retries generate fresh nonces and may create another saved history item after a partial receipt.
Tray and shortcut calls share the selected receiver action module. It uses discovery before a remembered endpoint, reports an unavailable explicitly selected receiver, and returns busy while another action is running. An absent selection retains the first-paired-device fallback. The action deadline includes capture, although an already-running native Windows capture must finish before its task can be joined.
The tests cover real TCP transfers and induced effect failures with isolated settings/history. App checks decode real PNG bytes through WPF after deleting their history file and verify that slow optional preview does not delay acknowledgement. Native clipboard contention, toast delivery, and a full transfer between two physical PCs remain interactive checks.
See ADR-0002 for the design and replay scope.