Last active
October 1, 2025 13:59
-
-
Save 777genius/8ca0a71b1fe23805159a7505814ffd33 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| param( | |
| [int]$MouseJitterPx = 12, | |
| [int]$ClickTestCount = 1, | |
| [switch]$SkipNotepad | |
| ) | |
| function Try-Run { | |
| param([string]$Name, [scriptblock]$Code) | |
| $ok = $true; $out = "" | |
| try { $val = & $Code; if ($null -ne $val) { $out = ($val | Out-String) } } | |
| catch { $ok = $false; $out = ($_ | Out-String) } | |
| [pscustomobject]@{ name = $Name; ok = $ok; output = ($out -replace '\s+$','') } | |
| } | |
| $report = [ordered]@{} | |
| function Add-Section { param([string]$k, $v) $script:report[$k] = $v } | |
| # 1) System | |
| Add-Section "System" @( | |
| (Try-Run "OS" { [System.Environment]::OSVersion | Format-List * }) | |
| (Try-Run "Machine" { "MachineName=$([Environment]::MachineName); User=$([Environment]::UserName)" }) | |
| (Try-Run "Bitness" { "Is64BitOS=$([Environment]::Is64BitOperatingSystem); Is64BitProcess=$([Environment]::Is64BitProcess)" }) | |
| (Try-Run "EnvArch" { "PROCESSOR_ARCHITECTURE=$env:PROCESSOR_ARCHITECTURE; PROCESSOR_ARCHITEW6432=$env:PROCESSOR_ARCHITEW6432; SystemRoot=$env:SystemRoot; WINDIR=$env:WINDIR" }) | |
| ) | |
| # 2) PowerShell | |
| Add-Section "PowerShell" @( | |
| (Try-Run "PSVersionTable" { $PSVersionTable | Format-List * }) | |
| (Try-Run "ExecutionPolicy" { Get-ExecutionPolicy -List | Format-Table -Auto | Out-String }) | |
| (Try-Run "IsAdmin" { [bool]([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) }) | |
| ) | |
| # 3) Shell paths | |
| $sysRoot = $env:SystemRoot; if (-not $sysRoot) { $sysRoot = $env:WINDIR } | |
| Add-Section "ShellPaths" @( | |
| (Try-Run "Get-Command pwsh,powershell" { Get-Command pwsh,powershell -ErrorAction SilentlyContinue | Select-Object Name,Path,Version | Format-Table -Auto | Out-String }) | |
| (Try-Run "TypicalPaths" { | |
| $paths = @( | |
| "C:\Program Files\PowerShell\7\pwsh.exe", | |
| "C:\Program Files\PowerShell\7-preview\pwsh.exe", | |
| (Join-Path $sysRoot "System32\WindowsPowerShell\v1.0\powershell.exe"), | |
| (Join-Path $sysRoot "Sysnative\WindowsPowerShell\v1.0\powershell.exe"), | |
| (Join-Path $sysRoot "SysWOW64\WindowsPowerShell\v1.0\powershell.exe") | |
| ) | |
| $paths | ForEach-Object { "{0} = {1}" -f $_, (Test-Path $_) } | |
| }) | |
| ) | |
| # 4) APIs | |
| Add-Section "APIs" @( | |
| (Try-Run "cscript" { Get-Command cscript -ErrorAction SilentlyContinue | Select-Object Path | Format-Table -Auto | Out-String }) | |
| (Try-Run "COM_WScriptShell" { $ws = New-Object -ComObject WScript.Shell; "OK: $($ws -ne $null)" }) | |
| (Try-Run "LoadForms" { Add-Type -AssemblyName System.Windows.Forms; "OK" }) | |
| (Try-Run "LoadDrawing" { Add-Type -AssemblyName System.Drawing; "OK" }) | |
| ) | |
| # 5) Key tests (SendKeys) | |
| Add-Section "KeyTests_SendKeys" @( | |
| (Try-Run "SendKeys_Hello123" { | |
| Add-Type -AssemblyName System.Windows.Forms | |
| [System.Windows.Forms.SendKeys]::SendWait("Hello123"); "OK (sent Hello123)" | |
| }) | |
| ) | |
| # 6) VBScript key test | |
| Add-Section "KeyTests_VBScript" @( | |
| (Try-Run "VBScript_SendKeys" { | |
| $tmp = Join-Path $env:TEMP "sendkeys_diag.vbs" | |
| @' | |
| Set WshShell = WScript.CreateObject("WScript.Shell") | |
| WScript.Sleep 200 | |
| WshShell.SendKeys "Hello via VBS" | |
| '@ | Out-File -FilePath $tmp -Encoding ASCII -Force | |
| try { & cscript //nologo $tmp | Out-Null; "OK (VBS ran)" } finally { Remove-Item $tmp -Force -ErrorAction SilentlyContinue } | |
| }) | |
| ) | |
| # 7) SendInput (UNICODE) - 'A' | |
| Add-Section "KeyTests_SendInput" @( | |
| (Try-Run "SendInput_A" { | |
| $code = @" | |
| using System; | |
| using System.Runtime.InteropServices; | |
| public static class Kbd { | |
| [StructLayout(LayoutKind.Sequential)] public struct INPUT { public int type; public INPUTUNION U; } | |
| [StructLayout(LayoutKind.Explicit)] public struct INPUTUNION { [FieldOffset(0)] public KEYBDINPUT ki; } | |
| [StructLayout(LayoutKind.Sequential)] public struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } | |
| [DllImport("user32.dll")] public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); | |
| public const int INPUT_KEYBOARD = 1; | |
| public const uint KEYEVENTF_UNICODE = 0x0004; | |
| public const uint KEYEVENTF_KEYUP = 0x0002; | |
| public static void SendUnicode(ushort ch) { | |
| INPUT down = new INPUT(); down.type = INPUT_KEYBOARD; down.U.ki.wScan = ch; down.U.ki.wVk = 0; down.U.ki.dwFlags = KEYEVENTF_UNICODE; | |
| INPUT up = new INPUT(); up.type = INPUT_KEYBOARD; up.U.ki.wScan = ch; up.U.ki.wVk = 0; up.U.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; | |
| SendInput(1, ref down, Marshal.SizeOf(down)); | |
| SendInput(1, ref up, Marshal.SizeOf(up)); | |
| } | |
| } | |
| "@ | |
| if (-not ('Kbd' -as [type])) { Add-Type -TypeDefinition $code -Language CSharp -IgnoreWarnings } | |
| [Kbd]::SendUnicode(0x0041) | |
| "OK (sent 'A')" | |
| }) | |
| ) | |
| # 8) Notepad test (PID) | |
| if (-not $SkipNotepad) { | |
| Add-Section "NotepadTest" @( | |
| (Try-Run "StartNotepad" { $p = Start-Process notepad -PassThru; Start-Sleep -Milliseconds 500; "PID=$($p.Id)"; $script:npid = $p.Id }) | |
| (Try-Run "COM_ActivateAndType" { | |
| $ws = New-Object -ComObject WScript.Shell | |
| $ok = $ws.AppActivate([int]$script:npid) | |
| Start-Sleep -Milliseconds 200 | |
| if ($ok) { $ws.SendKeys("Hello via COM"); "OK (COM sent by PID)" } else { "WARN: AppActivate failed" } | |
| }) | |
| (Try-Run "StopNotepad" { | |
| Get-Process -Id $script:npid -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue | |
| "Stopped" | |
| }) | |
| ) | |
| } | |
| # 9) Mouse tests | |
| Add-Section "MouseTests" @( | |
| (Try-Run "JitterMove" { | |
| Add-Type -AssemblyName System.Windows.Forms | |
| Add-Type -AssemblyName System.Drawing | |
| $p=[System.Windows.Forms.Cursor]::Position | |
| [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($p.X+$MouseJitterPx,$p.Y) | |
| Start-Sleep -Milliseconds 50 | |
| [System.Windows.Forms.Cursor]::Position = $p | |
| "OK (moved +$MouseJitterPx px and back)" | |
| }) | |
| (Try-Run "ClickCenter" { | |
| if ($ClickTestCount -le 0) { return "Skipped" } | |
| $sig = @" | |
| using System; | |
| using System.Runtime.InteropServices; | |
| public static class Clicker{ | |
| [DllImport("user32.dll")] public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, IntPtr dwExtraInfo); | |
| public const uint LEFTDOWN=0x0002; public const uint LEFTUP=0x0004; | |
| } | |
| "@ | |
| Add-Type -TypeDefinition $sig -Language CSharp -IgnoreWarnings | Out-Null | |
| Add-Type -AssemblyName System.Windows.Forms | |
| Add-Type -AssemblyName System.Drawing | |
| $b=[System.Windows.Forms.Screen]::PrimaryScreen.Bounds | |
| $cx=[int]($b.X + ($b.Width/2)); $cy=[int]($b.Y + ($b.Height/2)) | |
| $prev=[System.Windows.Forms.Cursor]::Position | |
| for($i=0;$i -lt $ClickTestCount;$i++){ | |
| [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($cx,$cy) | |
| [Clicker]::mouse_event([Clicker]::LEFTDOWN,0,0,0,[IntPtr]::Zero) | |
| Start-Sleep -Milliseconds 10 | |
| [Clicker]::mouse_event([Clicker]::LEFTUP,0,0,0,[IntPtr]::Zero) | |
| Start-Sleep -Milliseconds 100 | |
| } | |
| [System.Windows.Forms.Cursor]::Position = $prev | |
| "OK (clicked $ClickTestCount x at center)" | |
| }) | |
| ) | |
| "`n==== TEXT SUMMARY ====" | |
| $report.Keys | ForEach-Object { | |
| "`n>>> $_" | |
| $section = $report[$_] | |
| foreach ($item in $section) { | |
| "[{0}] ok={1}`n{2}" -f $item.name, $item.ok, $item.output | |
| } | |
| } | |
| "`n==== JSON (copy this to share) ====" | |
| $report | ConvertTo-Json -Depth 6 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment