Physical scan-code paste for remote PCs.
  • C# 96.2%
  • PowerShell 2.9%
  • Just 0.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Marcin Wisniowski 4ab06d8656
All checks were successful
ci / verify (push) Successful in 2m47s
pages / publish (push) Successful in 1m46s
fix: center palette before first frame
2026-09-26 12:37:26 -04:00
.forgejo/workflows feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
.github/workflows feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
docs fix: center palette before first frame 2026-09-26 12:37:26 -04:00
scripts feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
src/LISSTech.KeyPaste fix: center palette before first frame 2026-09-26 12:37:26 -04:00
tests/LISSTech.KeyPaste.Tests fix: store runtime data under ProgramData 2026-09-26 11:44:56 -04:00
.editorconfig feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
.gitattributes feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
.gitignore feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
CHANGELOG.md fix: store runtime data under ProgramData 2026-09-26 11:44:56 -04:00
Directory.Build.props feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
Directory.Packages.props feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
global.json feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
justfile feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
LICENSE feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
LISSTech.KeyPaste.slnx feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
NOTICE feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00
README.md fix: store runtime data under ProgramData 2026-09-26 11:44:56 -04:00
SECURITY.md feat: launch LISSTech KeyPaste 2026-09-26 11:27:05 -04:00

LISSTech KeyPaste — type anywhere
Forgejo CI Windows 10 and 11 .NET 10 Entrust EV signed Apache 2.0

⌨️ LISSTech KeyPaste

Clipboard blocked? Type it anyway.

KeyPaste turns text into layout-aware physical scan-code transitions for Windows remote and virtual consoles that refuse normal paste.

🌐 Landing page · 📦 Latest release · 🛡️ Security · 🧭 Changelog

Tip

Press the global shortcut, paste or type into the command palette, press Enter, then click the destination. KeyPaste handles the rest.

Important

KeyPaste stays local. Submitted text is held only in memory and is never written to settings, logs, telemetry, or a network service.


🧭 Table of contents


🚧 Why KeyPaste

Remote consoles often block Ctrl+V, clipboard redirection, Unicode VK_PACKET, or synthetic text APIs. The result is familiar: a password, recovery key, command, or path is on your clipboard—but the destination accepts only physical-looking keyboard input.

KeyPaste uses the active Windows keyboard layout to translate confirmed text into:

Stage KeyPaste behavior
Preflight Validates the complete string before sending a single key
Mapping Resolves characters through the active foreground keyboard layout
Input Emits explicit scan-code key-down, hold, key-up, and modifier transitions
Targeting Captures click-release through a pass-through low-level hook—even inside Hyper-V Enhanced Session
Privacy Keeps text in memory; never logs or persists it

No clipboard forwarding. No guest agent. No target-specific plugin.


✨ Product tour

KeyPaste command palette with syntax-colored text

Fast command palette

A PowerToys Run–inspired surface with adaptive Fluent styling, a centered caret, Cascadia/Consolas monospace text, red digits, and blue symbols.

Enter arms · Shift+Enter adds a line · Esc cancels.

Deliberate controls

Configure the shortcut, targeting mode, key timing, click delay, and timeout without fighting legacy Win32 widgets.

Adaptive light/dark palette, custom segmented controls, high-DPI artwork, and a compact notification-area menu.

KeyPaste Fluent settings window

🏁 How it works

sequenceDiagram
    autonumber
    actor User
    participant Palette as KeyPaste palette
    participant Hook as Target monitor
    participant Mapper as Layout mapper
    participant Win32 as SendInput
    participant Target as RDP / Hyper-V / VMware

    User->>Palette: Press global shortcut
    User->>Palette: Paste or type text
    User->>Palette: Enter
    Palette->>Hook: Arm mouse-up + Escape hooks
    Note over Hook: Non-activating hint follows pointer
    User->>Target: Click destination
    Hook-->>Palette: Pass click through + report release
    Palette->>Mapper: Validate complete text
    Mapper->>Win32: Build timed scan-code sequence
    Win32->>Target: Physical key transitions
    Target-->>User: Exact text appears

The five-second version

  1. Press your hotkey.
  2. Paste or type text.
  3. Press Enter.
  4. Click the destination.
  5. Done.

🧱 Architecture

flowchart LR
    Hotkey["⌨️ Global hotkey"] --> Palette["✨ Fluent command palette"]
    Tray["📍 Notification-area menu"] --> Palette
    Palette --> Memory["🔒 In-memory text"]
    Memory --> Monitor["🖱️ Pass-through target hooks"]
    Monitor --> Layout["🗺️ Active keyboard layout"]
    Layout --> Planner["🧮 Scan-code planner"]
    Planner --> Sender["⚡ Timed SendInput engine"]
    Sender --> RDP["Remote Desktop"]
    Sender --> HyperV["Hyper-V VMConnect"]
    Sender --> VMware["VMware console"]
    Sender --> Support["Remote-support viewers"]

    classDef ui fill:#e8f2ff,stroke:#0067b8,color:#10233f;
    classDef core fill:#fff4f3,stroke:#c8102e,color:#3b1015;
    classDef target fill:#f3f4f6,stroke:#374151,color:#111827;
    class Hotkey,Tray,Palette ui;
    class Memory,Monitor,Layout,Planner,Sender core;
    class RDP,HyperV,VMware,Support target;

Design invariants

  • Validate first; never type a partial unsupported string.
  • Pass target clicks through unchanged.
  • Release every hook and modifier on success, timeout, cancellation, and failure.
  • Never log text, screenshots, target details, or credentials.
  • Stay at ordinary-user integrity with asInvoker.

🖥️ Compatibility

Surface Status Notes
Microsoft Remote Desktop / Windows App ✅ Physical scan-code path
Hyper-V VMConnect ✅ Basic and Enhanced Session tested
VMware console ✅ Works where clipboard paste is blocked
Native remote-support viewers ✅ Viewer policy can still reject synthetic input
Browser-based consoles ✅ Requires the browser to accept host keyboard events
Windows sign-in fields ✅ When exposed through an ordinary remote console
UAC secure desktop ❌ Intentionally outside the process integrity boundary
BitLocker / firmware / pre-boot UI ❌ Not reachable through ordinary Windows SendInput
Higher-integrity target ⚠️ Run both applications at the same integrity level

📦 Install

Signed release

  1. Open Releases.
  2. Download LISSTech.KeyPaste-<version>-win-x64.zip.
  3. Verify SHA256SUMS.
  4. Extract and run LISSTech.KeyPaste.exe.

The release is self-contained: the target workstation does not need a preinstalled .NET runtime.

Trust

Production executables are:

  • Authenticode-signed by LISS Consulting Corp.
  • backed by an Entrust EV Code Signing certificate;
  • SHA-256 signed;
  • RFC 3161 timestamped through DigiCert; and
  • verified with Windows Authenticode policy before packaging.

🚀 Use

Palette

Input Action
Configured global shortcut Open KeyPaste
Ctrl+V Paste text into the palette
Enter Arm target selection
Shift+Enter Insert a newline
Esc Cancel without typing
Left-button release Select target and begin typing

Notification-area icon

  • Double-click: open settings
  • Right-click → Open KeyPaste: open the palette
  • Right-click → Settings: configure behavior
  • Right-click → Exit: unregister the hotkey and stop

⚙️ Settings

Settings live at:

%ProgramData%\LISS Technologies\LISSTech.KeyPaste\settings.json

Existing settings from %LOCALAPPDATA%\LISSTech\KeyPaste\settings.json are migrated once and the legacy file is removed after the ProgramData write succeeds.

Setting Purpose
Global shortcut System-wide palette activation
Click target Arm, follow the pointer, then type after click-release
Focused window Type into the window restored after the palette closes
Key delay Hold/gap timing for slow remote input transports
After click Gives the target time to establish focus
Arm timeout Automatically cancels stale target selection

🛡️ Security boundaries

flowchart TB
    subgraph OrdinaryUser["Ordinary user session"]
        UI["Palette + settings"]
        Buffer["Ephemeral text buffer"]
        Hooks["Mouse-up / Escape hooks"]
        Input["Scan-code sender"]
        UI --> Buffer --> Hooks --> Input
    end

    Input -. blocked .-> SecureDesktop["UAC secure desktop"]
    Input -. blocked .-> HigherIntegrity["Higher-integrity processes"]
    Input --> SameIntegrity["Same-integrity local / remote console"]
  • No network client exists in the application.
  • No telemetry SDK is referenced.
  • Clipboard contents and submitted text are never persisted.
  • Low-level hooks observe only left-button release and Escape while armed.
  • Hooks always call CallNextHookEx; KeyPaste never swallows the user's click.
  • See SECURITY.md for private vulnerability reporting.

🧪 Build and test

Requirements

  • Windows 10 or 11
  • .NET SDK 10.0.401
  • Windows SDK 10.0.26100 for release signing
  • Optional: just 1.58+
just ci

Equivalent commands:

dotnet restore LISSTech.KeyPaste.slnx
dotnet format LISSTech.KeyPaste.slnx --verify-no-changes --no-restore
dotnet build LISSTech.KeyPaste.slnx --configuration Release --no-restore
dotnet test LISSTech.KeyPaste.slnx --configuration Release --no-build

The test suite covers settings normalization and persistence, hotkey validation, CRLF handling, Caps Lock compensation, Unicode rejection, physical modifier ordering, and native INPUT ABI size.


✍️ Signed releases

Unsigned local candidate:

./scripts/Build-Release.ps1 -Version 1.0.0

Production-signed package:

./scripts/Build-Release.ps1 -Version 1.0.0 -Sign

The release pipeline:

  1. restores locked dependencies;
  2. verifies formatting;
  3. runs all tests;
  4. publishes a self-contained single-file win-x64 executable;
  5. signs and timestamps it;
  6. verifies the complete Authenticode chain;
  7. creates the release ZIP; and
  8. writes SHA256SUMS.

The EV private key remains on its hardware token. CI intentionally creates unsigned candidates.


🗂️ Repository map

.
├── src/LISSTech.KeyPaste/          # WinForms application and native input engine
│   ├── Models/                     # Immutable user configuration
│   ├── Native/                     # Win32 ABI declarations
│   ├── Services/                   # Mapping, hooks, input, persistence
│   └── UI/                         # Fluent palette, settings, hint, menu renderer
├── tests/LISSTech.KeyPaste.Tests/  # Deterministic behavior tests
├── docs/                           # Static landing page and artwork
├── scripts/Build-Release.ps1       # Verify, publish, sign, package
├── .forgejo/workflows/             # Forgejo CI and Pages publication
└── justfile                        # Repeatable developer entry points

📚 Documentation


🤝 Contributing

  1. Create a focused branch.
  2. Keep clipboard text and target details out of logs and test fixtures.
  3. Add behavior tests for mapping or sequencing changes.
  4. Run just ci.
  5. Open a pull request with observed Windows verification.

Issues and pull requests are welcome on the internal Forgejo repository.


📜 License

Copyright © 2026 LISS Consulting Corp.

Licensed under the Apache License 2.0. LISSTech names and artwork remain trademarks of LISS Consulting Corp.; Apache 2.0 does not grant trademark rights.

Built for operators who need the text to land exactly where they clicked.

🌐 lisstech.com