如何可靠枚举Windows 7至11系统中的真实文件资源管理器窗口
枚举真实文件资源管理器窗口的PowerShell实现方案
我想在PowerShell脚本中枚举所有已打开的文件资源管理器窗口。我已经在其他帖子中找到了枚举所有explorer.exe窗口实例的方法,例如使用Shell.Application COM API:(New-Object -com "Shell.Application").windows()
但这个方法返回的结果超出了我的实际需求:我只需要展示磁盘或网络上实际文件的「真实」文件资源管理器窗口,不需要仅作为各类控制面板窗口容器的「虚假」explorer.exe实例。也就是鼠标悬停在任务栏文件资源管理器图标上时显示的实例列表。请问如何才能可靠实现这一需求,且最好兼容Windows 7到11全版本?
以下是我验证过不可靠的方案:
- 将窗口标题与「Control Panel」「Windows Update」等已知字符串对比的方案价值有限,只能排除最常见的情况,且仅适用于英文版本Windows。
- 尝试匹配文件资源管理器窗口类的方案不可行:所有实例的类名都是「CabinetWClass」,即便是控制面板窗口也不例外。
- 真实实例存在类名为「UIRibbonWorkPane」的子窗口、控制面板没有的特征不可靠,因为功能区可以被手动禁用。
我的脚本中已经包含了封装WIN32 API调用的C#声明,因此提供C#代码片段也可以满足需求。
2021年10月10日更新
基于@simon-mourier的回答,目前最优的实现算法可总结如下:
$self = $window.Document.Folder.Self $ClassID = $Self.ExtendedProperty("System.NamespaceCLSID") $BaseClassID = $Self.Path.Substring(2,38) # 需配合有效性校验,若截取内容不是UUID则清空该值 # 少数已确认属于文件系统、但不会设置$Self.IsFileSystem标识的CLSID列表 $FileExplorerIDs = ( # Windows 10 "f02c1a0d-be21-4350-88b0-7367fc96ef3c", # 网络 "679f85cb-0220-4080-b29b-5540cc05aab6", # 快速访问 "20d04fe0-3aea-1069-a2d8-08002b30309d", # 此电脑 # Windows 7 "031e4825-7b94-4dc3-b131-e946b44c8dd5" # 库 ) if ($Self.IsFileSystem) { $AppType = "File Explorer" } elseif ($FileExplorerIDs -contains "$ClassID") { $AppType = "File Explorer" } elseif ($BaseClassID -eq "{26EE0668-A00A-44D7-9371-BEB064C98683}") { $AppType = "Control Panel" } elseif ("{$ClassID}" -eq "{D20EA4E1-3957-11D2-A40B-0C5020524153}") { $AppType = "Control Panel" # Windows 7 管理工具 } elseif ($Self.Name -eq $Self.Path) { # 待优化:当前判断逻辑可靠性不足 $AppType = "Search Results" # 例如"索引位置中的搜索结果"这类窗口 } else { $AppType = "Unknown" }
包含未定义字段处理、无效值排除等完整安全校验的算法已有公开实现可以参考。
内容的提问来源于stack exchange,提问作者Jean-François Larvoire
相关产品推荐
相关产品推荐

