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

如何用PowerShell的Register-ObjectEvent检测进程MainWindowTitle变化

检测进程MainWindowTitle变化的实现问题

我一直在寻找能检测进程MainWindowTitle(或对应属性)变化的.NET事件相关示例,但毫无收获。

检测文件内容变化时,我可以直接使用以下代码:

function Register-FileWatcherEvent {
    param (
        [string]$folder,
        [string]$file,
        [string]$SourceIdentifier = 'File_Changed'
    )

    $watcher = New-Object IO.FileSystemWatcher $folder, $file -Property @{
        IncludeSubdirectories = $false
        EnableRaisingEvents = $true
    }
    $watcher.NotifyFilter = 'LastWrite'

    Register-ObjectEvent $watcher -EventName 'Changed' -SourceIdentifier $SourceIdentifier
}

但要为MainWindowTitle或对应属性的变化注册事件,应该使用什么对象、属性和通知器?

第二次尝试

我尝试用WinEventHooks(完全摸不着门道)

虽然注册了一些事件,但它会在鼠标悬停时触发,而非标题变化时...

Add-Type -TypeDefinition @"
    using System;
    using System.Runtime.InteropServices;
    public static class User32 {
        public delegate void WinEventDelegate(
            IntPtr hWinEventHook, 
            uint eventType, 
            IntPtr hwnd, 
            int idObject, 
            int idChild, 
            uint dwEventThread, 
            uint dwmsEventTime);
        [DllImport("user32.dll")]
        public static extern IntPtr SetWinEventHook(
            uint eventMin, 
            uint eventMax, 
            IntPtr hmodWinEventProc, 
            WinEventDelegate lpfnWinEventProc, 
            uint idProcess, 
            uint idThread, uint dwFlags);
        [DllImport("user32.dll")]
        public static extern bool UnhookWinEvent(IntPtr hWinEventHook);
    }
"@

$processId = (Get-Process -Name notepad).Id

$WinEventDelegate = [User32+WinEventDelegate]{
    param (
        $hWinEventHook, 
        $eventType, 
        $hwnd, 
        $idObject, 
        $idChild, 
        $dwEventThread, 
        $dwmsEventTime
    )

    if ($eventType -eq 0x800C) {
        $windowTitle = Get-Process -Id $processId | 
            Select-Object -ExpandProperty MainWindowTitle
        
        Write-Host "Window title changed to: $windowTitle"
    }
}

$hWinEventHook = [User32]::SetWinEventHook(
    0x800C, 
    0x800C, 
    [IntPtr]::Zero, 
    $WinEventDelegate, 
    $processId, 
    0, 
    0
)


$handler = {
    param (
        $sender, 
        $eventArgs
    )
    
    $windowTitle = Get-Process -Id $processId | 
        Select-Object -ExpandProperty MainWindowTitle
    
    Write-Host "Window title changed to: $windowTitle"
}

Register-ObjectEvent -InputObject $null `
    -EventName EventRecord `
    -Action $handler `
    -SourceIdentifier "WindowTitleChanged" `
    -SupportEvent

# 取消注册事件可使用以下命令:
# Unregister-Event -SourceIdentifier "WindowTitleChanged"

0x800C对应EVENT_OBJECT_NAMECHANGE,但它可能对应不同类型的对象。所以我是不是需要在每次事件触发时,检查到底是什么发生了变化?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:17:47