|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
#requires -Version 5.1 <# .SYNOPSIS Runs in the background and intercepts Ctrl+V to simulate typing. .DESCRIPTION This script registers a global hotkey for Ctrl+V. When you press Ctrl+V, it "types" the contents of your clipboard instead of performing a normal paste. This is designed for use with remote consoles (like vSphere, Promox, or other no-VNC clients) that do not allow direct copy-pasting. .USAGE 1. Run this script in a PowerShell window. 2. The script will remain running in the background. 3. Copy any text you want to your clipboard. 4. Click on your target console window (vSphere, Proxmox, etc.). 5. Press Ctrl+V. 6. The script will "type" the clipboard contents into the console. 7. To stop the script, simply close this PowerShell window. #> # --- Load Required Assemblies --- try { Add-Type -AssemblyName System.Windows.Forms } catch { Write-Error "Failed to load System.Windows.Forms assembly. This script requires it to function." exit 1 } # --- Define Win32 API Functions for Hotkey --- $signature = @" [DllImport("user32.dll")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); [DllImport("user32.dll")] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool PeekMessage(out System.Windows.Forms.Message lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg); "@ # *** FIX IS HERE *** # We must add -ReferencedAssemblies to tell the C# compiler where to find "System.Windows.Forms.Message" Add-Type -MemberDefinition $signature -Name "User32" -Namespace "Win32" -ReferencedAssemblies "System.Windows.Forms" -PassThru | Out-Null # --- SCRIPT PARAMETERS --- # The delay (in milliseconds) between each keystroke. # Dumb consoles (like VNC) may drop characters if this is too fast. # Increase this value if you experience missed letters. $keyDelay = 50 # 50ms is a good, reliable starting point. # --- Hotkey Action Function --- function Perform-TypingAction { param( [int]$Delay ) # 1. Get text from the clipboard $textToType = $null try { if ([System.Windows.Forms.Clipboard]::ContainsText()) { $textToType = [System.Windows.Forms.Clipboard]::GetText() } } catch { Write-Warning "Failed to access clipboard: $_" return } # 2. Check if we have text if ([string]::IsNullOrEmpty($textToType)) { Write-Host "Hotkey pressed, but clipboard is empty. No action taken." return } Write-Host "Hotkey pressed! Typing clipboard contents..." # 3. Loop through each character and send it foreach ($char in $textToType.ToCharArray()) { $charString = $char.ToString() # SendKeys has 7 special characters that must be "escaped" # by wrapping them in curly braces {}. # These are: + ^ % ~ ( ) { } # We must also escape the braces themselves. if ("+^%~(){}".Contains($charString)) { $charString = "{$charString}" } try { [System.Windows.Forms.SendKeys]::SendWait($charString) } catch { Write-Error "Failed to send keystroke '$_'. Aborting." return # Stop typing on error } # Wait a small amount of time before sending the next key. Start-Sleep -Milliseconds $Delay } Write-Host "Typing complete." } # --- Main Hotkey Listener --- # 1. Register the hotkey (Ctrl+V) $hotkeyID = 1 $modCtrl = 0x0002 # MOD_CONTROL $vkV = 0x56 # Virtual-Key code for 'V' if (-not ([Win32.User32]::RegisterHotKey([IntPtr]::Zero, $hotkeyID, $modCtrl, $vkV))) { Write-Error "Failed to register hotkey Ctrl+V. Is it already in use by another program?" exit 1 } Write-Host "Hotkey Ctrl+V registered. Script is running in the background." -ForegroundColor Green Write-Host "Pressing Ctrl+V in any window will now type the clipboard contents." Write-Host "Press Ctrl+C or close this window to stop the script." # 2. Start the message loop to listen for the hotkey $msg = New-Object System.Windows.Forms.Message $WM_HOTKEY = 0x0312 $PM_REMOVE = 1 try { while ($true) { # Check for and remove messages from the queue $result = [Win32.User32]::PeekMessage([ref]$msg, [IntPtr]::Zero, 0, 0, $PM_REMOVE) if ($result) { # Check if the message is our hotkey if ($msg.Msg -eq $WM_HOTKEY -and $msg.WParam.ToInt32() -eq $hotkeyID) { # This is our hotkey! try { Perform-TypingAction -Delay $keyDelay } catch { Write-Error "An error occurred during typing: $_" } } } # Don't spin the CPU to 100% Start-Sleep -Milliseconds 50 } } finally { # This block runs when the user presses Ctrl+C or closes the window [Win32.User32]::UnregisterHotKey([IntPtr]::Zero, $hotkeyID) | Out-Null Write-Host "Hotkey unregistered. Exiting." -ForegroundColor Yellow } |