问题描述
我正在尝试获取 Windows 资源管理器窗口的当前文件夹位置。 使用此代码段,我可以迭代所有窗口并获取它们的位置。 但是,我需要将它们与它们的窗口句柄进行匹配,以便我可以根据文件夹位置操作窗口样式、位置、父级、标题等。
或者,是否可以从 HWND 获取 InternetExplorer 对象?
public void doStuff()
{
var t = Type.GetTypeFromProgID("Shell.Application");
var o = Activator.CreateInstance(t) as Shell32.Shell;
try
{
var ws = o.Application.Windows();
for (int i = 0; i < ws.Count; i++)
{
var ie = ws.Item(i);
if (ie == null)
continue;
var path = System.IO.Path.GetFileName((string)ie.FullName);
if (path.ToLower() != "explorer.exe")
continue;
// Gets the folder that it is showing
temp = ie.LocationURL.ToString();
temp = new Uri(temp).LocalPath;
// How can I get the window handle?
// ie.hwnd returns the top most window handle
// So if the explorer window is embedded,it returns the wrong window handle
}
}
catch (Exception x)
{
Console.log(x.Message);
}
finally
{
if (o != null)
Marshal.FinalReleaseComObject(o);
}
}
解决方法
编辑:
不知道是什么让你的代码花了这么长时间。在 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)
Navigate2 Method void Navigate2 (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)
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 框架的 mnid 中时,这很容易被忽略。它公开了以下方法和属性:
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)
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
通过 Self
的 Folder
属性检索:
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