You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Powershell绑定已打开窗口实现键鼠指令发送及同步缩放功能求助

PowerShell 窗口嵌入+指令发送+同步缩放完整实现

以下是纯原生实现的完整可运行代码,覆盖窗口绑定、同步缩放、按键发送三个核心需求,无需依赖WASP等第三方模块。


前置依赖声明

首先导入所需Win32 API和系统程序集:

# 加载所需程序集
Add-Type -AssemblyName System.Windows.Forms
Add-Type -Namespace Win32Functions -Name NativeMethods -MemberDefinition @'
    [DllImport("user32.dll")]
    public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
    [DllImport("user32.dll")]
    public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);
    [DllImport("user32.dll")]
    public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
    [DllImport("user32.dll")]
    public static extern bool SetProcessDPIAware();
'@
# 开启DPI适配避免缩放偏移
[Win32Functions.NativeMethods]::SetProcessDPIAware() | Out-Null

完整功能Demo代码

# 窗口状态控制函数(兼容你已有的实现)
function Set-WindowStyle {
    param(
        [Parameter()]
        [ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE', 
                     'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED', 
                     'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')]
        $Style = 'SHOW',
        [Parameter(Mandatory=$true)]
        $MainWindowHandle
    )
    $WindowStates = @{
        FORCEMINIMIZE   = 11; HIDE            = 0
        MAXIMIZE        = 3;  MINIMIZE        = 6
        RESTORE         = 9;  SHOW            = 5
        SHOWDEFAULT     = 10; SHOWMAXIMIZED   = 3
        SHOWMINIMIZED   = 2;  SHOWMINNOACTIVE = 7
        SHOWNA          = 8;  SHOWNOACTIVATE  = 4
        SHOWNORMAL      = 1
    }
    [Win32Functions.NativeMethods]::ShowWindowAsync($MainWindowHandle, $WindowStates[$Style]) | Out-Null
}

# --------------------------
# 1. 创建主窗体
# --------------------------
$mainForm = New-Object System.Windows.Forms.Form
$mainForm.Text = "窗口绑定工具"
$mainForm.Size = New-Object System.Drawing.Size(800,600)
$mainForm.StartPosition = "CenterScreen"

# 左侧数据录入区域
$inputPanel = New-Object System.Windows.Forms.Panel
$inputPanel.Dock = "Left"
$inputPanel.Width = 300
$inputPanel.Padding = New-Object System.Windows.Forms.Padding(10)

$txtInput = New-Object System.Windows.Forms.TextBox
$txtInput.Multiline = $true
$txtInput.Dock = "Top"
$txtInput.Height = 400
$txtInput.PlaceholderText = "请输入要发送的内容"

$btnSubmit = New-Object System.Windows.Forms.Button
$btnSubmit.Text = "提交到目标窗口"
$btnSubmit.Dock = "Bottom"
$btnSubmit.Height = 40

$inputPanel.Controls.Add($txtInput)
$inputPanel.Controls.Add($btnSubmit)

# 右侧目标窗口嵌入容器
$embedContainer = New-Object System.Windows.Forms.Panel
$embedContainer.Dock = "Fill"
$embedContainer.BackColor = [System.Drawing.Color]::LightGray

$mainForm.Controls.Add($embedContainer)
$mainForm.Controls.Add($inputPanel)

# --------------------------
# 2. 绑定目标窗口逻辑(示例为绑定记事本,可替换为你需要的进程)
# --------------------------
# 获取已运行的记事本,不存在则自动启动
$targetProc = Get-Process notepad -ErrorAction SilentlyContinue
if(-not $targetProc){
    $targetProc = Start-Process notepad -PassThru
    Start-Sleep -Milliseconds 500 # 等待窗口初始化完成
}
$targetHwnd = $targetProc.MainWindowHandle

# 绑定窗口到容器
Set-WindowStyle -Style SHOWNORMAL -MainWindowHandle $targetHwnd
[Win32Functions.NativeMethods]::SetParent($targetHwnd, $embedContainer.Handle) | Out-Null
# 初始调整目标窗口填满容器
[Win32Functions.NativeMethods]::MoveWindow($targetHwnd, 0, 0, $embedContainer.ClientSize.Width, $embedContainer.ClientSize.Height, $true) | Out-Null

# --------------------------
# 3. 父窗体缩放同步功能实现
# --------------------------
$embedContainer.Add_Resize({
    if($targetHwnd -ne [IntPtr]::Zero){
        [Win32Functions.NativeMethods]::MoveWindow($targetHwnd, 0, 0, $embedContainer.ClientSize.Width, $embedContainer.ClientSize.Height, $true) | Out-Null
    }
})

# --------------------------
# 4. 数据校验+按键发送功能实现
# --------------------------
$btnSubmit.Add_Click({
    # 自定义数据校验规则:示例为移除非中文、英文、数字、常用标点的非法字符
    $cleanContent = $txtInput.Text -replace '[^\w\u4e00-\u9fa5,.!? ]', ''
    if([string]::IsNullOrWhiteSpace($cleanContent)){
        [System.Windows.Forms.MessageBox]::Show("输入内容为空或全部为非法字符")
        return
    }
    # 激活目标窗口确保按键发送成功
    [Win32Functions.NativeMethods]::SetForegroundWindow($targetHwnd) | Out-Null
    Start-Sleep -Milliseconds 100 # 等待窗口激活完成
    # 发送处理后的内容,特殊控制字符需要用{}转义,比如发送+要写为{+}
    [System.Windows.Forms.SendKeys]::SendWait($cleanContent)
    # 可追加发送回车:[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
})

# 可选:窗体关闭时恢复目标窗口为独立窗口
$mainForm.Add_FormClosing({
    [Win32Functions.NativeMethods]::SetParent($targetHwnd, [IntPtr]::Zero) | Out-Null
    Set-WindowStyle -Style RESTORE -MainWindowHandle $targetHwnd
})

# 运行窗体
$mainForm.ShowDialog() | Out-Null

注意事项

  • 权限匹配:如果目标程序以管理员权限运行,PowerShell也需要以管理员权限启动,否则SetParent绑定会失败
  • 特殊字符转义:SendKeys发送的内容中如果包含+^%~()[]{}这些特殊控制字符,需要用大括号包裹转义
  • 老旧应用适配:部分不支持子窗口模式的老旧应用绑定后可能出现显示异常,可尝试先移除目标窗口的标题栏再绑定
  • 发送时延:如果出现内容发送不全的情况,可适当延长激活窗口后的Sleep时间,或者拆分内容逐段发送

内容的提问来源于stack exchange,提问作者Xanderu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:45:02