编辑:
不知道是什么让您的代码花费了这么长时间。在 PowerShell 中,检索 HWND-FolderPath 关联需要 90 毫秒,而不是 15 秒!我希望它在编译代码中更快:
PS C:\> $shell.windows() | select HWND, @{ N = 'Path' ; E = { $_.Document.Folder.Self.Path }}
HWND Path
---- ----
1180948 C:\Users\keith\Documents
198040 C:\Users\keith\Pictures
328592 C:\Windows
721672 C:\Users\keith\Videos
198538 C:\Users\keith\DummyDesktop
PS C:\> Measure-Command -Expression {$shell.windows() | select HWND, @{ N = 'Path' ; E = { $_.Document.Folder.Self.Path }}}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 90
Ticks : 904963
TotalDays : 1.04741087962963E-06
TotalHours : 2.51378611111111E-05
TotalMinutes : 0.00150827166666667
TotalSeconds : 0.0904963
TotalMilliseconds : 90.4963
我的回答中的逐步方法是为了理解。假设之前创建了 Shell 对象,您只需要上面的一行。
我刚刚通过 PowerShell 中的Shell.Application COM 对象使用文件资源管理器窗口,因此您必须进行一些代码翻译,但对象、属性和方法应该一样。
Shell 对象的Windows 方法返回一个Shellwindows 对象,该对象“表示属于Shell 的打开窗口的集合”。这包含两个 Internet Explorer 和 文件资源管理器(包括 控制面板)窗口:
PS C:\>>$Shell = New-Object -ComObject shell.application
PS C:\> $shell.windows() |
>> Format-Table -AutoSize -Wrap -Property Name, TYpe, LocationName, LocationURL -GroupBy FullName
FullName: C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE
Name Type LocationName LocationURL
---- ---- ------------ -----------
Internet Explorer HTML Document Google https://www.google.com/?gws_rd=ssl#spf=1627718454134
FullName: C:\WINDOWS\explorer.exe
Name Type LocationName LocationURL
---- ---- ------------ -----------
File Explorer Documents file:///C:/Users/keith/Documents
File Explorer Control Panel
File Explorer Libraries
File Explorer Quick access
File Explorer Network
但所有窗口确实都是InternetExplorer 对象。
PS C:\>>$Shell.Windows() | Get-Member
TypeName: System.__ComObject#{d30c1661-cdaf-11d0-8a3e-00c04fc9e26e}
Name MemberType Definition
---- ---------- ----------
ClientToWindow Method void ClientToWindow (int, int)
ExecWB Method void ExecWB (OLECMDID, OLECMDEXECOPT, Variant, Variant)
GetProperty Method Variant GetProperty (string)
GoBack Method void GoBack ()
GoForward Method void GoForward ()
GoHome Method void GoHome ()
GoSearch Method void GoSearch ()
Navigate Method void Navigate (string, Variant, Variant, Variant, Variant)
Navigate2 Method void Navigate2 (Variant, Variant, Variant, Variant, Variant)
PutProperty Method void PutProperty (string, Variant)
QueryStatusWB Method OLECMDF QueryStatusWB (OLECMDID)
Quit Method void Quit ()
Refresh Method void Refresh ()
Refresh2 Method void Refresh2 (Variant)
ShowBrowserBar Method void ShowBrowserBar (Variant, Variant, Variant)
Stop Method void Stop ()
AddressBar Property bool AddressBar () {get} {set}
Application Property IDispatch Application () {get}
Busy Property bool Busy () {get}
Container Property IDispatch Container () {get}
Document Property IDispatch Document () {get}
FullName Property string FullName () {get}
FullScreen Property bool FullScreen () {get} {set}
Height Property int Height () {get} {set}
HWND Property int HWND () {get}
Left Property int Left () {get} {set}
LocationName Property string LocationName () {get}
LocationURL Property string LocationURL () {get}
MenuBar Property bool MenuBar () {get} {set}
Name Property string Name () {get}
Offline Property bool Offline () {get} {set}
Parent Property IDispatch Parent () {get}
Path Property string Path () {get}
ReadyState Property tagREADYSTATE ReadyState () {get}
RegisterAsBrowser Property bool RegisterAsBrowser () {get} {set}
RegisterAsDropTarget Property bool RegisterAsDropTarget () {get} {set}
Resizable Property bool Resizable () {get} {set}
Silent Property bool Silent () {get} {set}
StatusBar Property bool StatusBar () {get} {set}
StatusText Property string StatusText () {get} {set}
TheaterMode Property bool TheaterMode () {get} {set}
ToolBar Property int ToolBar () {get} {set}
Top Property int Top () {get} {set}
TopLevelContainer Property bool TopLevelContainer () {get}
Type Property string Type () {get}
Visible Property bool Visible () {get} {set}
Width Property int Width () {get} {set}
TypeMame 的 GUID 表明它本质上是 IWebBrowser2 接口的包装器。
这是您接下来要访问的容易被忽视的Document 属性。该链接揭示了为什么当您在 Explorer/Shell 框架中时很容易忽略这一点。它公开了以下方法和属性:
PS C:\>>$FolderWIndows[0].Document | Get-Member
TypeName: System.__ComObject#{29ec8e6c-46d3-411f-baaa-611a6c9cac66}
Name MemberType Definition
---- ---------- ----------
FilterView Method void FilterView (string)
PopupItemMenu Method string PopupItemMenu (FolderItem, Variant, Variant)
SelectedItems Method FolderItems SelectedItems ()
SelectItem Method void SelectItem (Variant, int)
SelectItemRelative Method void SelectItemRelative (int)
Application Property IDispatch Application () {get}
CurrentViewMode Property uint CurrentViewMode () {get} {set}
FocusedItem Property FolderItem FocusedItem () {get}
Folder Property Folder Folder () {get}
FolderFlags Property uint FolderFlags () {get} {set}
GroupBy Property string GroupBy () {get} {set}
IconSize Property int IconSize () {get} {set}
Parent Property IDispatch Parent () {get}
Script Property IDispatch Script () {get}
SortColumns Property string SortColumns () {get} {set}
ViewOptions Property int ViewOptions () {get}
但它的 Folder 属性返回窗口中显示的文件夹的Folder 对象。 Folder 对象及其关联的FolderItem 对象公开了与Shell 命名空间中的项关联的属性和方法。 FolderItem 是通过 Folder 的 Self 属性检索的:
PS C:\>>$FolderWIndows.Document.Folder | Get-Member
TypeName: System.__ComObject#{a7ae5f64-c4d7-4d7f-9307-4d24ee54b841}
Name MemberType Definition
---- ---------- ----------
CopyHere Method void CopyHere (Variant, Variant)
DismissedWebViewBarricade Method void DismissedWebViewBarricade ()
GetDetailsOf Method string GetDetailsOf (Variant, int)
Items Method FolderItems Items ()
MoveHere Method void MoveHere (Variant, Variant)
NewFolder Method void NewFolder (string, Variant)
ParseName Method FolderItem ParseName (string)
Synchronize Method void Synchronize ()
Application Property IDispatch Application () {get}
HaveToShowWebViewBarricade Property bool HaveToShowWebViewBarricade () {get}
OfflineStatus Property int OfflineStatus () {get}
Parent Property IDispatch Parent () {get}
ParentFolder Property Folder ParentFolder () {get}
Self Property FolderItem Self () {get}
ShowWebViewBarricade Property bool ShowWebViewBarricade () {get} {set}
Title Property string Title () {get}
PS C:\>>$FolderWIndows.Document.Folder.Self | Get-Member
TypeName: System.__ComObject#{edc817aa-92b8-11d1-b075-00c04fc33aa5}
Name MemberType Definition
---- ---------- ----------
ExtendedProperty Method Variant ExtendedProperty (string)
InvokeVerb Method void InvokeVerb (Variant)
InvokeVerbEx Method void InvokeVerbEx (Variant, Variant)
Verbs Method FolderItemVerbs Verbs ()
Application Property IDispatch Application () {get}
GetFolder Property IDispatch GetFolder () {get}
GetLink Property IDispatch GetLink () {get}
IsBrowsable Property bool IsBrowsable () {get}
IsFileSystem Property bool IsFileSystem () {get}
IsFolder Property bool IsFolder () {get}
IsLink Property bool IsLink () {get}
ModifyDate Property Date ModifyDate () {get} {set}
Name Property string Name () {get} {set}
Parent Property IDispatch Parent () {get}
Path Property string Path () {get}
Size Property int Size () {get}
Type Property string Type () {get}
这是您想要的 FolderItem 的 Path 属性。
PS C:\>>$FolderWIndows | select HWND,
>> @{ N = 'Title' ; E = { $_.Document.Folder.Title }},
>> @{ N = 'Path' ; E = { $_.Document.Folder.Self.Path }}
HWND Title Path
---- ----- ----
3080380 Documents C:\Users\keith\Documents
68614 Control Panel ::{26EE0668-A00A-44D7-9371-BEB064C98683}
853746 Libraries ::{031E4825-7B94-4DC3-B131-E946B44C8DD5}
1245532 Quick access ::{679F85CB-0220-4080-B29B-5540CC05AAB6}
199810 Network ::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}
相对于文件资源管理器和 Shell 命名空间,FolderItem 的路径可能不明确。您可以通过递归评估 ParentFolder 对象来确定命名空间路径,直到到达桌面,即没有父级的 shell 命名空间的根目录。
Function Get-NSPath ( $oFolder )
{
If (( $oParent = $oFolder.ParentFolder ).ParentFolder )
{
(( Get-NSPath $oParent ) , $oFolder.Title ) -join '\'
}
ElseIf ( $oParent )
{
$oFolder.Title # Desktop/NavPane Item
}
} # If oFolder was the virtual Desktop, Namespace path is null.
从多个位置打开 DOcumentes 文件夹后:
$FolderWindows = $shell.Windows() | Where FullName -match 'explorer.exe$'
PS C:\>>$FolderWIndows | select HWND,
>> @{ N = 'Title' ; E = { $_.Document.Folder.Title }},
>> @{ N = 'Path' ; E = { $_.Document.Folder.Self.Path }},
>> @{ N = 'NameSpace' ; E = { Get-NSPath $_.Document.Folder }}
HWND Title Path NameSpace
---- ----- ---- ---------
265366 Documents C:\Users\keith\Documents This PC\Documents
331000 Documents C:\Users\keith\Documents Keith Miller\Documents
2950776 Documents C:\Users\keith\Documents This PC\Windows (C:)\Users\keith\Documents
396606 Documents C:\Users\keith\Documents Libraries\Documents\Documents