193 lines
7.3 KiB
PowerShell
193 lines
7.3 KiB
PowerShell
param(
|
|
[Parameter(Position=0, Mandatory=$true)]
|
|
[string]$Command,
|
|
|
|
[Parameter(Position=1, ValueFromRemainingArguments=$true)]
|
|
[string[]]$Params
|
|
)
|
|
|
|
# Load required assemblies
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
Add-Type -AssemblyName System.Drawing
|
|
Add-Type -AssemblyName UIAutomationClient
|
|
Add-Type -AssemblyName UIAutomationTypes
|
|
|
|
# C# P/Invoke for advanced Input
|
|
$code = @"
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
public class Win32 {
|
|
[DllImport("user32.dll")]
|
|
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
|
|
|
|
public const uint MOUSEEVENTF_LEFTDOWN = 0x02;
|
|
public const uint MOUSEEVENTF_LEFTUP = 0x04;
|
|
public const uint MOUSEEVENTF_RIGHTDOWN = 0x08;
|
|
public const uint MOUSEEVENTF_RIGHTUP = 0x10;
|
|
public const uint KEYEVENTF_KEYUP = 0x02;
|
|
}
|
|
"@
|
|
Add-Type -TypeDefinition $code -Language CSharp
|
|
|
|
switch ($Command.ToLower()) {
|
|
"mouse" {
|
|
if ($Params.Count -lt 2) { Write-Error "Usage: mouse x y"; exit 1 }
|
|
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point([int]$Params[0], [int]$Params[1])
|
|
Write-Host "Moved mouse to $($Params[0]), $($Params[1])"
|
|
}
|
|
|
|
"click" {
|
|
[Win32]::mouse_event([Win32]::MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
|
|
[Win32]::mouse_event([Win32]::MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
|
|
Write-Host "Clicked"
|
|
}
|
|
|
|
"rightclick" {
|
|
[Win32]::mouse_event([Win32]::MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
|
|
[Win32]::mouse_event([Win32]::MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0)
|
|
Write-Host "Right Clicked"
|
|
}
|
|
|
|
"type" {
|
|
if ($Params.Count -lt 1) { Write-Error "Usage: type 'text'"; exit 1 }
|
|
$text = $Params -join " "
|
|
[System.Windows.Forms.SendKeys]::SendWait($text)
|
|
Write-Host "Typed: $text"
|
|
}
|
|
|
|
"key" {
|
|
if ($Params.Count -lt 1) { Write-Error "Usage: key KEYNAME"; exit 1 }
|
|
$k = $Params[0].ToUpper()
|
|
|
|
if ($k -eq "LWIN" -or $k -eq "WIN") {
|
|
[Win32]::keybd_event(0x5B, 0, 0, 0)
|
|
[Win32]::keybd_event(0x5B, 0, 0x02, 0)
|
|
} elseif ($k -eq "ENTER") {
|
|
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
} elseif ($k -eq "TAB") {
|
|
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
} else {
|
|
[System.Windows.Forms.SendKeys]::SendWait("{$k}")
|
|
}
|
|
Write-Host "Pressed: $k"
|
|
}
|
|
|
|
"screen" {
|
|
$w = [System.Windows.Forms.SystemInformation]::VirtualScreen.Width
|
|
$h = [System.Windows.Forms.SystemInformation]::VirtualScreen.Height
|
|
Write-Host "Screen Resolution: $w x $h"
|
|
}
|
|
|
|
"screenshot" {
|
|
if ($Params.Count -lt 1) { $file = "screenshot.png" } else { $file = $Params[0] }
|
|
$fullPath = [System.IO.Path]::GetFullPath($file)
|
|
|
|
$bmp = New-Object System.Drawing.Bitmap ([System.Windows.Forms.SystemInformation]::VirtualScreen.Width, [System.Windows.Forms.SystemInformation]::VirtualScreen.Height)
|
|
$g = [System.Drawing.Graphics]::FromImage($bmp)
|
|
$g.CopyFromScreen(0, 0, 0, 0, $bmp.Size)
|
|
$bmp.Save($fullPath)
|
|
$g.Dispose()
|
|
$bmp.Dispose()
|
|
Write-Host "Screenshot saved to $fullPath"
|
|
}
|
|
|
|
"find" {
|
|
if ($Params.Count -lt 1) { Write-Error "Usage: find 'Name'"; exit 1 }
|
|
$targetName = $Params -join " "
|
|
|
|
Write-Host "Searching for VISIBLE UI Element: '$targetName'..."
|
|
|
|
$root = [System.Windows.Automation.AutomationElement]::RootElement
|
|
$cond = New-Object System.Windows.Automation.PropertyCondition([System.Windows.Automation.AutomationElement]::NameProperty, $targetName)
|
|
|
|
# Find ALL matches, then filter for visibility (to avoid phantom offscreen elements)
|
|
$collection = $root.FindAll([System.Windows.Automation.TreeScope]::Descendants, $cond)
|
|
$found = $false
|
|
|
|
if ($collection) {
|
|
foreach ($element in $collection) {
|
|
try {
|
|
if (-not $element.Current.IsOffscreen) {
|
|
$rect = $element.Current.BoundingRectangle
|
|
if ($rect.Width -gt 0 -and $rect.Height -gt 0) {
|
|
$centerX = [int]($rect.X + ($rect.Width / 2))
|
|
$centerY = [int]($rect.Y + ($rect.Height / 2))
|
|
Write-Host "Found Visible '$targetName' at ($centerX, $centerY)"
|
|
Write-Host "COORD:$centerX,$centerY"
|
|
$found = $true
|
|
break # Stop at first visible match
|
|
}
|
|
}
|
|
} catch {}
|
|
}
|
|
}
|
|
|
|
if (-not $found) {
|
|
Write-Host "Element '$targetName' not found visible on desktop."
|
|
}
|
|
}
|
|
|
|
"uiclick" {
|
|
if ($Params.Count -lt 1) { Write-Error "Usage: uiclick 'Name'"; exit 1 }
|
|
$targetName = $Params -join " "
|
|
Write-Host "Searching & Clicking: '$targetName'..."
|
|
|
|
$root = [System.Windows.Automation.AutomationElement]::RootElement
|
|
$cond = New-Object System.Windows.Automation.PropertyCondition([System.Windows.Automation.AutomationElement]::NameProperty, $targetName)
|
|
$collection = $root.FindAll([System.Windows.Automation.TreeScope]::Descendants, $cond)
|
|
|
|
$found = $false
|
|
foreach ($element in $collection) {
|
|
try {
|
|
if (-not $element.Current.IsOffscreen) {
|
|
$rect = $element.Current.BoundingRectangle
|
|
if ($rect.Width -gt 0) {
|
|
$centerX = [int]($rect.X + ($rect.Width / 2))
|
|
$centerY = [int]($rect.Y + ($rect.Height / 2))
|
|
|
|
# Move & Click
|
|
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($centerX, $centerY)
|
|
Start-Sleep -Milliseconds 100
|
|
[Win32]::mouse_event([Win32]::MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
|
|
[Win32]::mouse_event([Win32]::MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
|
|
|
|
Write-Host "Clicked '$targetName' at ($centerX, $centerY)"
|
|
$found = $true
|
|
break
|
|
}
|
|
}
|
|
} catch {}
|
|
}
|
|
|
|
if (-not $found) { Write-Host "Could not find visible '$targetName' to click." }
|
|
}
|
|
|
|
"open" {
|
|
if ($Params.Count -lt 1) { Write-Error "Usage: open 'Path or URL'"; exit 1 }
|
|
$target = $Params -join " "
|
|
try {
|
|
Start-Process $target
|
|
Write-Host "Opened '$target'"
|
|
} catch {
|
|
Write-Error "Failed to open '$target': $_"
|
|
}
|
|
}
|
|
|
|
"apps" {
|
|
$apps = Get-Process | Where-Object { $_.MainWindowTitle -ne "" } | Select-Object Id, MainWindowTitle
|
|
if ($apps) {
|
|
$apps | Format-Table -AutoSize | Out-String | Write-Host
|
|
} else {
|
|
Write-Host "No visible applications found."
|
|
}
|
|
}
|
|
|
|
default {
|
|
Write-Host "Commands: mouse, click, rightclick, type, key, screen, screenshot, find, apps"
|
|
}
|
|
}
|