PowerShell获取活动窗口进程名与标题并赋值字符串的问题排查
问题分析与修复方案
核心问题点
- $screenTitle无法正常显示:你用
Select-Object MainWindowTitle得到的是包含MainWindowTitle属性的自定义对象,而非直接的字符串值,输出时只会展示对象结构而非属性内容。 - 空标题不进入Else分支:即便
MainWindowTitle值为空,$screenTitle仍是一个非空的对象,所以$screenTitle -ne $Null永远为真,不会触发Else逻辑。 - 额外隐患:
$myPid被初始化为[IntPtr]::Zero,但GetWindowThreadProcessId要求输出参数是Int32类型,类型不匹配可能导致PID获取异常。
修复后的代码
$code = @' [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out Int32 lpdwProcessId); '@ Add-Type $code -Name Utils -Namespace Win32 $myPid = 0 # 改为Int32类型的初始值 Do { $hwnd = [Win32.Utils]::GetForegroundWindow() $null = [Win32.Utils]::GetWindowThreadProcessId($hwnd, [ref] $myPid) # 只调用一次Get-Process,同时获取两个属性的字符串值 $targetProcess = Get-Process -Id $myPid -ErrorAction SilentlyContinue if ($targetProcess) { $processName = $targetProcess.ProcessName $screenTitle = $targetProcess.MainWindowTitle if (-not [string]::IsNullOrEmpty($screenTitle)) { "进程名: $processName" "窗口标题: $screenTitle" } else { Write-Host "无窗口标题" } } else { Write-Host "未找到对应PID的进程" } Start-Sleep -Milliseconds 3000 } While($True)
关键修改说明
- 直接获取属性值:跳过
Select-Object,直接通过进程对象的ProcessName和MainWindowTitle属性拿到字符串,解决对象类型导致的显示和判断问题。 - 准确判断空值:用
[string]::IsNullOrEmpty($screenTitle)判断标题是否为空字符串,比直接对比$null更贴合字符串类型的判断逻辑。 - 优化进程查询:仅调用一次
Get-Process并捕获结果,提升执行效率,同时添加错误处理避免无效PID导致的报错。 - 修正PID类型:将
$myPid初始化为0(Int32类型),与API要求的参数类型匹配,避免类型转换异常。
内容的提问来源于stack exchange,提问作者jeriru
相关产品推荐
相关产品推荐

