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

如何用PowerShell批量关闭MATRIS更新成功提示窗口

看起来你在批量处理MATRIS更新的弹窗关闭时遇到了麻烦——手动杀PID可行但没法自动化,试过进程名和窗口标题的命令都没成功,还担心32位进程的影响。我来给你几个针对性的解决方案,应该能搞定这个问题:

方案一:通过窗口标题精准关闭弹窗

更新成功的窗口一般会有固定标题(比如“MATRIS 更新完成”或类似),这是最可靠的定位方式,因为进程名可能有变体,而窗口标题通常不会变。

首先,先确认弹窗的准确标题:打开一个更新成功窗口,运行下面的PowerShell命令,找到对应窗口的MainWindowTitle:

Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object Name, MainWindowTitle, Path

然后用这个脚本关闭所有匹配该标题的窗口(用系统API直接发送关闭消息,比强制杀进程更温和):

# 替换为你实际查到的更新成功窗口标题
$targetWindowTitle = "MATRIS 更新成功"

# 导入Windows API实现窗口关闭
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
    [DllImport("user32.dll")]
    public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
    [DllImport("user32.dll")]
    public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
    public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
    [DllImport("user32.dll")]
    public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount);
    public const uint WM_CLOSE = 0x0010;
}
"@

# 枚举所有窗口,找到匹配标题的并关闭
$matchingWindows = New-Object System.Collections.Generic.List[IntPtr]
$enumCallback = [Win32+EnumWindowsProc]{
    param($hWnd, $lParam)
    $titleBuilder = New-Object System.Text.StringBuilder(256)
    [Win32]::GetWindowText($hWnd, $titleBuilder, $titleBuilder.Capacity)
    if ($titleBuilder.ToString() -eq $targetWindowTitle) {
        $matchingWindows.Add($hWnd)
    }
    return $true
}
[Win32]::EnumWindows($enumCallback, [IntPtr]::Zero)

foreach ($windowHandle in $matchingWindows) {
    [Win32]::PostMessage($windowHandle, [Win32]::WM_CLOSE, 0, 0)
    Write-Host "已关闭窗口: $targetWindowTitle"
}

方案二:通过进程名/路径关闭(兼容32位进程)

如果窗口标题不太好抓,或者弹窗和进程绑定紧密,可以直接定位进程。32位进程在64位系统里也能被PowerShell正确识别,只要用对命令:

按进程名关闭

找到进程的准确名称(不带.exe后缀也可以),运行:

# 替换为实际的进程名,比如MatrisInstaller.APCIPLUS
Get-Process -Name "MatrisInstaller.APCIPLUS" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue

-Force确保进程被强制关闭,-ErrorAction SilentlyContinue避免找不到进程时抛出错误。

按进程路径关闭(更精准)

如果有多个同名进程,用路径匹配更保险:

# 替换为进程路径的特征片段,比如包含MATRIS安装目录的部分
Get-CimInstance Win32_Process | Where-Object {$_.ExecutablePath -like "*MatrisInstaller.APCIPLUS*.exe"} | ForEach-Object {
    Stop-Process -Id $_.ProcessId -Force
    Write-Host "已关闭进程: $($_.ExecutablePath)"
}

Get-CimInstance Win32_Process能可靠获取所有32/64位进程的完整路径,比Get-Process的Path属性更稳定。

方案三:带监控逻辑的完整自动化脚本

因为你是批量处理15个更新包,需要脚本持续监控并自动关闭弹窗,不用手动触发:

# 配置参数:替换为你的实际窗口标题和进程名
$targetWindowTitle = "MATRIS 更新成功"
$targetProcessName = "MatrisInstaller.APCIPLUS"
$monitorDurationHours = 1 # 监控时长,根据你的更新总时长调整
$checkIntervalSeconds = 5 # 每5秒检查一次

# 定义关闭目标窗口和进程的函数
function Close-Targets {
    # 关闭匹配标题的窗口
    Add-Type @"
    using System;
    using System.Runtime.InteropServices;
    public class Win32 {
        [DllImport("user32.dll")]
        public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
        public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount);
        public const uint WM_CLOSE = 0x0010;
    }
"@

    $matchingWindows = New-Object System.Collections.Generic.List[IntPtr]
    $enumCallback = [Win32+EnumWindowsProc]{
        param($hWnd, $lParam)
        $titleBuilder = New-Object System.Text.StringBuilder(256)
        [Win32]::GetWindowText($hWnd, $titleBuilder, $titleBuilder.Capacity)
        if ($titleBuilder.ToString() -eq $targetWindowTitle) {
            $matchingWindows.Add($hWnd)
        }
        return $true
    }
    [Win32]::EnumWindows($enumCallback, [IntPtr]::Zero)

    foreach ($windowHandle in $matchingWindows) {
        [Win32]::PostMessage($windowHandle, [Win32]::WM_CLOSE, 0, 0)
        Write-Host "$(Get-Date -Format 'HH:mm:ss') 已关闭窗口: $targetWindowTitle"
    }

    # 同时关闭对应进程(防止窗口无响应)
    Get-Process -Name $targetProcessName -ErrorAction SilentlyContinue | ForEach-Object {
        Stop-Process -Id $_.Id -Force
        Write-Host "$(Get-Date -Format 'HH:mm:ss') 已关闭进程: $($_.Name)"
    }
}

# 开始监控循环
$endTime = (Get-Date).AddHours($monitorDurationHours)
Write-Host "开始监控,将持续到 $endTime"
while ((Get-Date) -lt $endTime) {
    Close-Targets
    Start-Sleep -Seconds $checkIntervalSeconds
}
Write-Host "监控结束"

关键注意事项

  1. 先确认准确的窗口标题/进程名:一定要用Get-Process或任务管理器确认,不要凭记忆写,否则脚本会找不到目标。
  2. 32位进程无需特殊处理:上面的命令都兼容32/64位系统,Get-CimInstance和Get-Process都能正确识别32位进程。
  3. 为什么你之前的命令没成功?
    • 路径匹配可能太严格:比如你用$_.Path -like "MatrisInstaller.APCIPLUS",但实际路径是C:\xxx\MatrisInstaller.APCIPLUS.exe,应该改成$_.Path -like "*MatrisInstaller.APCIPLUS*.exe"(加通配符)。
    • 进程名可能带.exe后缀:比如实际进程名是MatrisInstaller.APCIPLUS.exe,而你写的是不带后缀的名称,导致Get-Process找不到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:40:08