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

PowerShell实现类人化鼠标移动及脚本终止方法问询

PowerShell 鼠标控制问题解决方案

1. 实现类人化速度的鼠标移动

要避免鼠标瞬间跳转,核心是分步移动+短间隔休眠,模拟人类移动的平滑节奏,还可加入微小速度变化更贴近真实操作。

先导入必要的Win32 API和定义移动函数:

Add-Type -AssemblyName System.Windows.Forms
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
    [DllImport("user32.dll")]
    public static extern bool SetCursorPos(int X, int Y);
    [DllImport("user32.dll")]
    public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
}
"@

function MoveMouseSmoothly {
    param(
        [int]$StartX,
        [int]$StartY,
        [int]$TargetX,
        [int]$TargetY,
        [int]$DurationMs = 1000 # 默认1秒完成移动,数值越小速度越快
    )

    # 计算总步数,取X/Y方向差值的最大值保证移动均匀
    $steps = [Math]::Max([Math]::Abs($TargetX - $StartX), [Math]::Abs($TargetY - $StartY))
    if ($steps -eq 0) { return }

    $stepX = ($TargetX - $StartX) / $steps
    $stepY = ($TargetY - $StartY) / $steps
    $sleepMs = $DurationMs / $steps

    for ($i = 0; $i -lt $steps; $i++) {
        $currentX = [Math]::Round($StartX + ($stepX * $i))
        $currentY = [Math]::Round($StartY + ($stepY * $i))
        [Win32]::SetCursorPos($currentX, $currentY)
        Start-Sleep -Milliseconds $sleepMs
    }

    # 确保最终精准到达目标坐标
    [Win32]::SetCursorPos($TargetX, $TargetY)
}

# 使用示例:从当前位置移动到(500,500),耗时1.5秒
$currentPos = [System.Windows.Forms.Cursor]::Position
MoveMouseSmoothly -StartX $currentPos.X -StartY $currentPos.Y -TargetX 500 -TargetY 500 -DurationMs 1500

# 后续点击操作
[Win32]::mouse_event(0x0002, 0, 0, 0, 0) # 按下左键
Start-Sleep -Milliseconds 50
[Win32]::mouse_event(0x0004, 0, 0, 0, 0) # 释放左键

2. 实现曲线/随机曲线移动路径

2.1 贝塞尔曲线平滑移动

通过三阶贝塞尔曲线生成自然的弧形路径,需要定义起点、两个控制点和终点:

function MoveMouseBezier {
    param(
        [int]$StartX,
        [int]$StartY,
        [int]$CtrlX1,
        [int]$CtrlY1,
        [int]$CtrlX2,
        [int]$CtrlY2,
        [int]$TargetX,
        [int]$TargetY,
        [int]$DurationMs = 1500
    )

    $steps = 100 # 曲线细分步数,数值越大路径越平滑
    $sleepMs = $DurationMs / $steps

    for ($t = 0; $t -le 1; $t += 1/$steps) {
        $tInv = 1 - $t
        # 计算贝塞尔曲线上的X坐标
        $x = [Math]::Round(
            $tInv*$tInv*$tInv*$StartX +
            3*$tInv*$tInv*$t*$CtrlX1 +
            3*$tInv*$t*$t*$CtrlX2 +
            $t*$t*$t*$TargetX
        )
        # 计算贝塞尔曲线上的Y坐标
        $y = [Math]::Round(
            $tInv*$tInv*$tInv*$StartY +
            3*$tInv*$tInv*$t*$CtrlY1 +
            3*$tInv*$t*$t*$CtrlY2 +
            $t*$t*$t*$TargetY
        )
        [Win32]::SetCursorPos($x, $y)
        Start-Sleep -Milliseconds $sleepMs
    }

    [Win32]::SetCursorPos($TargetX, $TargetY)
}

# 使用示例:从(100,100)经两个控制点到(800,600)
MoveMouseBezier -StartX 100 -StartY 100 -CtrlX1 300 -CtrlY1 500 -CtrlX2 600 -CtrlY2 200 -TargetX 800 -TargetY 600 -DurationMs 2000

2.2 随机曲线移动(模拟人类不规则操作)

在直线移动基础上加入动态随机偏移,越接近终点偏移越小,更符合人类操作习惯:

function MoveMouseRandomCurve {
    param(
        [int]$StartX,
        [int]$StartY,
        [int]$TargetX,
        [int]$TargetY,
        [int]$DurationMs = 1200,
        [int]$MaxRandomOffset = 15 # 最大随机偏移量,数值越大路径越不规则
    )

    $steps = [Math]::Max([Math]::Abs($TargetX - $StartX), [Math]::Abs($TargetY - $StartY)) * 2
    if ($steps -eq 0) { return }

    $stepX = ($TargetX - $StartX) / $steps
    $stepY = ($TargetY - $StartY) / $steps
    $sleepMs = $DurationMs / $steps

    $currentX = $StartX
    $currentY = $StartY

    for ($i = 0; $i -lt $steps; $i++) {
        # 越接近终点,随机偏移越小
        $offsetFactor = 1 - ($i / $steps)
        $randomX = (Get-Random -Minimum (-$MaxRandomOffset) -Maximum $MaxRandomOffset) * $offsetFactor
        $randomY = (Get-Random -Minimum (-$MaxRandomOffset) -Maximum $MaxRandomOffset) * $offsetFactor

        $currentX += $stepX + $randomX
        $currentY += $stepY + $randomY

        # 确保坐标在屏幕范围内(可选)
        $currentX = [Math]::Clamp([Math]::Round($currentX), 0, [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width - 1)
        $currentY = [Math]::Clamp([Math]::Round($currentY), 0, [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height - 1)

        [Win32]::SetCursorPos($currentX, $currentY)
        Start-Sleep -Milliseconds $sleepMs
    }

    [Win32]::SetCursorPos($TargetX, $TargetY)
}

# 使用示例:从当前位置随机曲线移动到(600,400)
$currentPos = [System.Windows.Forms.Cursor]::Position
MoveMouseRandomCurve -StartX $currentPos.X -StartY $currentPos.Y -TargetX 600 -TargetY 400 -DurationMs 1500 -MaxRandomOffset 20

3. 终止后台运行的脚本

如果脚本在PowerShell窗口外持续运行,可用以下方式终止:

  • 任务管理器操作:打开任务管理器,找到powershell.exe或powershell_ise.exe进程,右键选择「结束任务」。
  • 命令行终止:打开新的PowerShell窗口,执行对应命令:
    # 终止所有PowerShell进程(谨慎使用,会关闭所有PowerShell窗口)
    Get-Process powershell,powershell_ise | Stop-Process -Force
    
    # 按脚本文件名精准终止(仅适用于从文件运行的脚本)
    Get-WmiObject Win32_Process | Where-Object { $_.CommandLine -match "你的脚本文件名.ps1" } | ForEach-Object { Stop-Process $_.ProcessId -Force }
    
  • 快捷键终止:如果脚本是在PowerShell ISE或普通PowerShell窗口启动的,回到对应窗口按Ctrl+C即可终止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:41:09