如何在PowerShell中按Z序获取多窗口进程的最近活跃实例?
按Windows Z序获取PureRef窗口对应的文件路径
要实现按最近活跃(Z序最高)的顺序返回PureRef窗口对应的文件路径,Get-Process无法直接提供Z序信息,需要借助Windows API来枚举窗口并确定其层级顺序。以下是具体的实现方案:
核心思路
- 调用Windows API枚举所有顶层窗口
- 筛选出归属PureRef进程的窗口
- 按Z序(从顶层到底层)排序这些窗口
- 从窗口标题中提取目标文件路径
完整函数实现
function Get-PureRef { # 加载所需的Windows API函数 Add-Type @" using System; using System.Runtime.InteropServices; using System.Collections.Generic; public class WindowInfo { public IntPtr HWnd { get; set; } public int ProcessId { get; set; } public string Title { get; set; } } public class WindowEnumerator { [DllImport("user32.dll")] private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); [DllImport("user32.dll")] private static extern bool GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); [DllImport("user32.dll")] private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount); private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); public static List<WindowInfo> GetTopLevelWindows() { List<WindowInfo> windows = new List<WindowInfo>(); EnumWindows((hWnd, lParam) => { int pid; GetWindowThreadProcessId(hWnd, out pid); int titleLength = GetWindowTextLength(hWnd); string title = string.Empty; if (titleLength > 0) { System.Text.StringBuilder sb = new System.Text.StringBuilder(titleLength + 1); GetWindowText(hWnd, sb, sb.Capacity); title = sb.ToString(); } windows.Add(new WindowInfo { HWnd = hWnd, ProcessId = pid, Title = title }); return true; }, IntPtr.Zero); return windows; } // 按Z序从顶层到底层排序窗口 public static List<WindowInfo> SortWindowsByZOrder(List<WindowInfo> windows) { List<WindowInfo> sortedWindows = new List<WindowInfo>(); IntPtr currentWnd = GetWindow(IntPtr.Zero, 0); // GW_HWNDFIRST:获取Z序最顶层的窗口 while (currentWnd != IntPtr.Zero) { var match = windows.Find(w => w.HWnd == currentWnd); if (match != null) { sortedWindows.Add(match); } currentWnd = GetWindow(currentWnd, 2); // GW_HWNDNEXT:获取下一个Z序的窗口 } return sortedWindows; } } "@ # 获取所有顶层窗口并筛选PureRef相关的 $allWindows = [WindowEnumerator]::GetTopLevelWindows() $pureRefWindows = $allWindows | Where-Object { $proc = Get-Process -Id $_.ProcessId -ErrorAction SilentlyContinue $proc -and $proc.ProcessName -eq "PureRef" -and $_.Title -match " - C:\\" } # 按Z序排序 $sortedWindows = [WindowEnumerator]::SortWindowsByZOrder($pureRefWindows) # 提取文件路径并输出 $sortedWindows | ForEach-Object { if ($_.Title -match " - (C:\\.*\.pur)$") { $matches[1] } } }
使用说明
在PowerShell中运行上述函数定义后,执行Get-PureRef即可得到按最近活跃顺序排列的PureRef文件路径列表:
Get-PureRef
输出示例:
C:\temp\Level Design 1.pur C:\temp\Car Shelf.pur C:\temp\Backgrounds_1.pur
此时(Get-PureRef)[0]会始终指向最近活跃窗口对应的文件路径,满足你的系统约定需求。
内容的提问来源于stack exchange,提问作者GaryAtlan82
相关产品推荐
相关产品推荐

