Add UIAutomation background injection for Roblox Studio
- bg_inject.ps1: PowerShell UIAutomation script that finds Studio command bar by AutomationId and injects Lua code without window focus - bg_inject.py: Python wrapper for bg_inject.ps1 - bg_inject_uia2.ps1: Discovery/debugging script for finding Studio UI controls - inject_full_gta.py: 7-step GTA city + COD weapons + enemies injection using background API - inject_gta_bg.py: Alternative multi-file GTA injection loader Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
164
bg_inject_uia2.ps1
Normal file
164
bg_inject_uia2.ps1
Normal file
@@ -0,0 +1,164 @@
|
||||
# Background injection into Roblox Studio using pure PowerShell + UIAutomation
|
||||
# Works when Studio is minimized, behind other windows, or in background
|
||||
|
||||
Add-Type -AssemblyName UIAutomationClient
|
||||
Add-Type -AssemblyName UIAutomationTypes
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
|
||||
# Find Studio
|
||||
$root = [System.Windows.Automation.AutomationElement]::RootElement
|
||||
$cond = New-Object System.Windows.Automation.PropertyCondition(
|
||||
[System.Windows.Automation.AutomationElement]::ControlTypeProperty,
|
||||
[System.Windows.Automation.ControlType]::Window
|
||||
)
|
||||
$windows = $root.FindAll([System.Windows.Automation.TreeScope]::Children, $cond)
|
||||
|
||||
$studio = $null
|
||||
foreach ($w in $windows) {
|
||||
try {
|
||||
if ($w.Current.Name -like "*Roblox Studio*") {
|
||||
$studio = $w
|
||||
break
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (-not $studio) {
|
||||
# Try by process
|
||||
$procs = Get-Process -Name "RobloxStudioBeta" -ErrorAction SilentlyContinue
|
||||
if ($procs) {
|
||||
$pidCond = New-Object System.Windows.Automation.PropertyCondition(
|
||||
[System.Windows.Automation.AutomationElement]::ProcessIdProperty,
|
||||
$procs[0].Id
|
||||
)
|
||||
$studio = $root.FindFirst([System.Windows.Automation.TreeScope]::Children, $pidCond)
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $studio) {
|
||||
Write-Output "ERROR: Roblox Studio not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Output "Found: $($studio.Current.Name)"
|
||||
|
||||
# Search for Edit controls (command bar)
|
||||
$editCond = New-Object System.Windows.Automation.PropertyCondition(
|
||||
[System.Windows.Automation.AutomationElement]::ControlTypeProperty,
|
||||
[System.Windows.Automation.ControlType]::Edit
|
||||
)
|
||||
|
||||
# Also check Document controls
|
||||
$docCond = New-Object System.Windows.Automation.PropertyCondition(
|
||||
[System.Windows.Automation.AutomationElement]::ControlTypeProperty,
|
||||
[System.Windows.Automation.ControlType]::Document
|
||||
)
|
||||
|
||||
$orCond = New-Object System.Windows.Automation.OrCondition($editCond, $docCond)
|
||||
$edits = $studio.FindAll([System.Windows.Automation.TreeScope]::Descendants, $orCond)
|
||||
|
||||
Write-Output "Found $($edits.Count) Edit/Document controls"
|
||||
|
||||
$commandBar = $null
|
||||
foreach ($e in $edits) {
|
||||
try {
|
||||
$name = $e.Current.Name
|
||||
$autoId = $e.Current.AutomationId
|
||||
$className = $e.Current.ClassName
|
||||
$bbox = $e.Current.BoundingRectangle
|
||||
Write-Output " Edit: name='$name' autoId='$autoId' class='$className' rect=$bbox"
|
||||
|
||||
# Check if it's the command bar
|
||||
if ($name -like "*command*" -or $autoId -like "*command*" -or $autoId -like "*script*") {
|
||||
$commandBar = $e
|
||||
Write-Output " -> MATCHED by name/autoId"
|
||||
break
|
||||
}
|
||||
} catch {
|
||||
Write-Output " Edit: (error reading properties)"
|
||||
}
|
||||
}
|
||||
|
||||
# If no match by name, try all edits and find one that supports ValuePattern
|
||||
if (-not $commandBar -and $edits.Count -gt 0) {
|
||||
Write-Output "`nNo name match. Trying ValuePattern on all edits..."
|
||||
foreach ($e in $edits) {
|
||||
try {
|
||||
$vp = $e.GetCurrentPattern([System.Windows.Automation.ValuePattern]::Pattern)
|
||||
if ($vp) {
|
||||
$val = $vp.Current.Value
|
||||
Write-Output " ValuePattern found: '$($val.Substring(0, [Math]::Min(60, $val.Length)))'"
|
||||
$commandBar = $e
|
||||
break
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $commandBar) {
|
||||
# List ALL descendants for debugging
|
||||
Write-Output "`nNo command bar found. Listing all controls..."
|
||||
$all = $studio.FindAll([System.Windows.Automation.TreeScope]::Descendants,
|
||||
[System.Windows.Automation.Condition]::TrueCondition)
|
||||
Write-Output "Total descendants: $($all.Count)"
|
||||
|
||||
$count = 0
|
||||
foreach ($a in $all) {
|
||||
if ($count -ge 80) { break }
|
||||
try {
|
||||
$ct = $a.Current.ControlType.ProgrammaticName
|
||||
$nm = $a.Current.Name
|
||||
$ai = $a.Current.AutomationId
|
||||
$cl = $a.Current.ClassName
|
||||
# Only show interesting ones
|
||||
if ($ct -match "Edit|Text|Document|Button|MenuItem|Tool" -or
|
||||
$ai -match "command|script|bar|input|console") {
|
||||
Write-Output " [$ct] name='$nm' autoId='$ai' class='$cl'"
|
||||
$count++
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
Write-Output "`nERROR: Could not identify command bar"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Set value using ValuePattern
|
||||
Write-Output "`nInjecting code..."
|
||||
$code = $args[0]
|
||||
if (-not $code) {
|
||||
$code = 'print("UI_AUTO_INJECT_OK")'
|
||||
}
|
||||
|
||||
try {
|
||||
$vp = $commandBar.GetCurrentPattern([System.Windows.Automation.ValuePattern]::Pattern)
|
||||
$vp.SetValue($code)
|
||||
Write-Output "SetValue OK"
|
||||
} catch {
|
||||
Write-Output "ValuePattern failed: $_"
|
||||
Write-Output "Trying keyboard simulation..."
|
||||
# Focus the element
|
||||
try {
|
||||
$commandBar.SetFocus()
|
||||
Start-Sleep -Milliseconds 200
|
||||
[System.Windows.Forms.SendKeys]::SendWait("^a") # Ctrl+A
|
||||
Start-Sleep -Milliseconds 100
|
||||
# Set clipboard and paste
|
||||
Set-Clipboard -Value $code
|
||||
[System.Windows.Forms.SendKeys]::SendWait("^v") # Ctrl+V
|
||||
Start-Sleep -Milliseconds 500
|
||||
} catch {
|
||||
Write-Output "Focus+SendKeys also failed: $_"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Send Enter to execute
|
||||
Start-Sleep -Milliseconds 300
|
||||
try {
|
||||
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
||||
Write-Output "Enter sent"
|
||||
} catch {
|
||||
Write-Output "SendKeys Enter failed: $_"
|
||||
}
|
||||
|
||||
Write-Output "`nSUCCESS: Code injected!"
|
||||
Reference in New Issue
Block a user