Get current explorer window path

Post your working scripts, libraries and tools for AHK v1.1 and older
AlexV
Posts: 1
Joined: 17 Nov 2019, 05:42

Get current explorer window path

17 Nov 2019, 05:51

I've been trying to find a good script to cleanly and reliably get the current path of an explorer window without tricks like reading it from the address bar or knowing the user profile name and so on. Having finally found the right interfaces and properties, I thought I'd share it for others:

Code: Select all

GetActiveExplorerPath()
{
	explorerHwnd := WinActive("ahk_class CabinetWClass")
	if (explorerHwnd)
	{
		for window in ComObjCreate("Shell.Application").Windows
		{
			if (window.hwnd==explorerHwnd)
			{
				return window.Document.Folder.Self.Path
			}
		}
	}
}
If the string it returns starts with :: then it's a special folder of some sort, and doesn't really have a path as such.
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Get current explorer window path

17 Nov 2019, 22:54

Thanks for sharing this.
godofOOF
Posts: 27
Joined: 22 Dec 2018, 06:03

Re: Get current explorer window path

07 Dec 2019, 09:56

how do you use this
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Get current explorer window path

07 Dec 2019, 11:11

Activate the file explorer window (via your script or manually), then call the function. If you are activating it manually, then you’ll need some way to trigger the function, like make it part of a hotkey subroutine. One way to call the function is to assign the returned value of the function to a variable:

Code: Select all

Path := GetActiveExplorerPath()
seohyeonhyeon
Posts: 1
Joined: 07 Jan 2021, 19:38

Re: Get current explorer window path

07 Jan 2021, 19:39

Thanks so much for posting! This is much better than what I had navigating up to the address bar.
MancioDellaVega
Posts: 83
Joined: 16 May 2020, 12:27
Location: Italy

Re: Get current explorer window path

08 Jan 2021, 14:52

This is another great code that i found here in the forum, it give you the path of the selected file

Code: Select all

q:: ; Get the Path to the Selected File in Explorer. 
      hwnd := WinExist("A")
      for Window in ComObjCreate("Shell.Application").Windows  
          if (window.hwnd==hwnd) {
              Selection := Window.Document.SelectedItems
              for Items in Selection
                  Path_to_Selection := Items.path
          }

      MsgBox % Path_to_Selection

return


Courses on AutoHotkey
flacito
Posts: 44
Joined: 06 Oct 2019, 11:43

Re: Get current explorer window path

09 Jan 2021, 17:37

MancioDellaVega wrote:
08 Jan 2021, 14:52
This is another great code that i found here in the forum, it give you the path of the selected file

Code: Select all

q:: ; Get the Path to the Selected File in Explorer. 
      hwnd := WinExist("A")
      for Window in ComObjCreate("Shell.Application").Windows  
          if (window.hwnd==hwnd) {
              Selection := Window.Document.SelectedItems
              for Items in Selection
                  Path_to_Selection := Items.path
          }

      MsgBox % Path_to_Selection

return


Would someone be so kind to make it such that the path to selection is copied to clipboard?
User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: Get current explorer window path

09 Jan 2021, 18:18

Replace MsgBox % Path_to_Selection with Clipboard:= Path_to_Selection
flacito
Posts: 44
Joined: 06 Oct 2019, 11:43

Re: Get current explorer window path

10 Jan 2021, 17:14

rommmcek wrote:
09 Jan 2021, 18:18
Replace MsgBox % Path_to_Selection with Clipboard:= Path_to_Selection
Perfect! Thanks :)
User avatar
svArtist
Posts: 62
Joined: 08 Mar 2015, 18:16

Re: Get current explorer window path

11 Mar 2021, 16:42

Oh this is great! :)

Although I ran into a Catastrophic Error, specifically: hwnd.
Apparently, that can fail to enumerate, and not even gracefully.
Here's my version that catches errors and also allows you to pass an already determined HWND.
  • If none is passed, it takes the active Explorer window.
    • If the active window isn't an Explorer Window, it takes the first one it can find.
if a specific HWND was passed but doesn't point to an Explorer window, it returns false (instead of looking for the best match; so you don't end up with an unexpected result)

Code: Select all

GetExplorerPath(hwnd=0){
	if(hwnd==0){
		explorerHwnd := WinActive("ahk_class CabinetWClass")
		if(explorerHwnd==0)
			explorerHwnd := WinExist("ahk_class CabinetWClass")
	}
	else
		explorerHwnd := WinExist("ahk_class CabinetWClass ahk_id " . hwnd)
	
	if (explorerHwnd){
		for window in ComObjCreate("Shell.Application").Windows{
			try{
				if (window && window.hwnd && window.hwnd==explorerHwnd)
					return window.Document.Folder.Self.Path
			}
		}
	}
	return false
}
:morebeard:
azowux
Posts: 3
Joined: 04 Oct 2018, 15:09

Re: Get current explorer window path

29 Sep 2021, 13:10

svArtist wrote:
11 Mar 2021, 16:42
Oh this is great! :)

Although I ran into a Catastrophic Error, specifically: hwnd.
Apparently, that can fail to enumerate, and not even gracefully.
Here's my version that catches errors and also allows you to pass an already determined HWND.
  • If none is passed, it takes the active Explorer window.
    • If the active window isn't an Explorer Window, it takes the first one it can find.
if a specific HWND was passed but doesn't point to an Explorer window, it returns false (instead of looking for the best match; so you don't end up with an unexpected result)

Code: Select all

GetExplorerPath(hwnd=0){
	if(hwnd==0){
		explorerHwnd := WinActive("ahk_class CabinetWClass")
		if(explorerHwnd==0)
			explorerHwnd := WinExist("ahk_class CabinetWClass")
	}
	else
		explorerHwnd := WinExist("ahk_class CabinetWClass ahk_id " . hwnd)
	
	if (explorerHwnd){
		for window in ComObjCreate("Shell.Application").Windows{
			try{
				if (window && window.hwnd && window.hwnd==explorerHwnd)
					return window.Document.Folder.Self.Path
			}
		}
	}
	return false
}
Been automating workflows on AHK for 4 years already. Gotta state even though currently I'm changing jobs and nobody understands my code's language (I just briefly say there's a huge library built on WinAPI), the community is alive as it has never been. Thanks a lot guys for your shares!
User avatar
Jamjize
Posts: 12
Joined: 16 Apr 2017, 05:17

Re: Get current explorer window path

19 Apr 2022, 11:49

@AlexV
Thank you very much!!! <3 <3 <3
flacito
Posts: 44
Joined: 06 Oct 2019, 11:43

Re: Get current explorer window path

30 Jun 2022, 07:13

azowux wrote:
29 Sep 2021, 13:10
svArtist wrote:
11 Mar 2021, 16:42
Oh this is great! :)

Although I ran into a Catastrophic Error, specifically: hwnd.
Apparently, that can fail to enumerate, and not even gracefully.
Here's my version that catches errors and also allows you to pass an already determined HWND.
  • If none is passed, it takes the active Explorer window.
    • If the active window isn't an Explorer Window, it takes the first one it can find.
if a specific HWND was passed but doesn't point to an Explorer window, it returns false (instead of looking for the best match; so you don't end up with an unexpected result)

Code: Select all

GetExplorerPath(hwnd=0){
	if(hwnd==0){
		explorerHwnd := WinActive("ahk_class CabinetWClass")
		if(explorerHwnd==0)
			explorerHwnd := WinExist("ahk_class CabinetWClass")
	}
	else
		explorerHwnd := WinExist("ahk_class CabinetWClass ahk_id " . hwnd)
	
	if (explorerHwnd){
		for window in ComObjCreate("Shell.Application").Windows{
			try{
				if (window && window.hwnd && window.hwnd==explorerHwnd)
					return window.Document.Folder.Self.Path
			}
		}
	}
	return false
}
Been automating workflows on AHK for 4 years already. Gotta state even though currently I'm changing jobs and nobody understands my code's language (I just briefly say there's a huge library built on WinAPI), the community is alive as it has never been. Thanks a lot guys for your shares!
after using it for so long, i now get a catastrophic error. But I dont know how to incorporate your fix in the code.
How does that go about?
User avatar
svArtist
Posts: 62
Joined: 08 Mar 2015, 18:16

Re: Get current explorer window path

22 Jul 2022, 12:58

flacito wrote:
30 Jun 2022, 07:13
[...]
after using it for so long, i now get a catastrophic error. But I dont know how to incorporate your fix in the code.
How does that go about?
Sorry, I don't seem to get email notifications for replies in this forum o_o

My adaptation should be a drop-in replacement.
paste the function in your script and use it simply like path := GetExplorerPath() when you want to get the "current" explorer window's path (active window if it's an Explorer window, otherwise the first matching window), or path := GetExplorerPath(hwnd) when you already have a specific window of which you want to get the path by passing its hwnd to the function
:morebeard:
User avatar
Avtem
Posts: 43
Joined: 01 Jun 2021, 02:20

Re: Get current explorer window path

29 Nov 2022, 09:27

@AlexV
You are a legend! Thank you
User avatar
Onurtag
Posts: 3
Joined: 13 Sep 2015, 12:49

Re: Get current explorer window path

15 Feb 2023, 00:50

Thanks for the function and the update.

The script wasn't working correctly for the Windows 11 Version 10.0.22621+ tabbed explorer so I added an extra window title check.
Also now if you run GetExplorerPath(0, false) it will only match the active window.

**Currently it doesn't work correctly if you have 2 opened tabs with the same title (such as C:\Folder1 and D:\Folder1.)

Code: Select all

GetExplorerPath(hwnd = 0, findWindow = true) {
	if (hwnd == 0) {
		explorerHwnd := WinActive("ahk_class CabinetWClass")
		if (findWindow && explorerHwnd == 0) {
			explorerHwnd := WinExist("ahk_class CabinetWClass")
		}
	} else {
		explorerHwnd := WinExist("ahk_class CabinetWClass ahk_id " . hwnd)
	}
	WinGetTitle, myTitle, ahk_id %explorerHwnd%
	if (explorerHwnd) {
		for window in ComObjCreate("Shell.Application").Windows {
			try {
				if (window && window.hwnd && window.hwnd == explorerHwnd && window.LocationName && window.LocationName == myTitle) {
					return window.Document.Folder.Self.Path
				}
			}
		}
	}
	return false
}
On my ExploreEverything script I have decided to mainly use these three lines below and only use GetExplorerPath() for special folders like Pictures/Documents/Movies etc.

Code: Select all

ControlGet, crumbHWND, Hwnd,, Breadcrumb Parent1, A
ControlGetText, RunPath, ToolbarWindow321, ahk_id %crumbHWND%
RunPath := StrSplit(RunPath, ": ")[2]
ntepa
Posts: 406
Joined: 19 Oct 2022, 20:52

Re: Get current explorer window path

15 Feb 2023, 02:54

This function can get the path in Windows 11 tabbed explorer:

Code: Select all

GetActiveExplorerPath() {
    hwnd := WinActive("ahk_class CabinetWClass")
    activeTab := 0
    try ControlGet, activeTab, Hwnd,, % "ShellTabWindowClass1", % "ahk_id" hwnd
    for w in ComObjCreate("Shell.Application").Windows {
        if (w.hwnd != hwnd)
            continue
        if activeTab {
            static IID_IShellBrowser := "{000214E2-0000-0000-C000-000000000046}"
            shellBrowser := ComObjQuery(w, IID_IShellBrowser, IID_IShellBrowser)
            DllCall(NumGet(numGet(shellBrowser+0)+3*A_PtrSize), "Ptr", shellBrowser, "UInt*", thisTab)
            if (thisTab != activeTab)
                continue
            ObjRelease(shellBrowser)
        }
        return w.Document.Folder.Self.Path
    }
}
User avatar
Onurtag
Posts: 3
Joined: 13 Sep 2015, 12:49

Re: Get current explorer window path

19 Feb 2023, 16:57

ntepa wrote:
15 Feb 2023, 02:54
This function can get the path in Windows 11 tabbed explorer:
Looks great! Thank you.
wpb
Posts: 146
Joined: 14 Dec 2015, 01:53

Re: Get current explorer window path

30 Aug 2023, 13:58

I have a simple version of GetActiveExplorerPath() that looks like this:

Code: Select all

GetExplorerCOMObject(hwndExplorerWindow := "")
{
	if !hwndExplorerWindow
		MouseGetPos(, , &hwndExplorerWindow)

	for Window in ComObject("Shell.Application").Windows
	{
		if (Window.hwnd = hwndExplorerWindow)
			return Window
	}
}
When I use it to get a COM handle on an Explorer window, that handle appears to persist even if I later do

Code: Select all

Window := ""
This means that if the window was one from an external drive, I can no longer "eject" it using the "Safely Remove Hardware" icon in the taskbar.

How do I release the COM object or the Window object properly, to stop this happening?
User avatar
svArtist
Posts: 62
Joined: 08 Mar 2015, 18:16

Re: Get current explorer window path

30 Aug 2023, 14:22

wpb wrote:
30 Aug 2023, 13:58
I have a simple version of GetActiveExplorerPath() that looks like this:

Code: Select all

GetExplorerCOMObject(hwndExplorerWindow := "")
{
	if !hwndExplorerWindow
		MouseGetPos(, , &hwndExplorerWindow)

	for Window in ComObject("Shell.Application").Windows
	{
		if (Window.hwnd = hwndExplorerWindow)
			return Window
	}
}
When I use it to get a COM handle on an Explorer window, that handle appears to persist even if I later do

Code: Select all

Window := ""
This means that if the window was one from an external drive, I can no longer "eject" it using the "Safely Remove Hardware" icon in the taskbar.

How do I release the COM object or the Window object properly, to stop this happening?
Not sure if this fits here.
You might have to open a new thread and request Lexicos's (or who ever else can speak to that) insight about the inner workings of AHK.
Unless the variable is global or otherwise passed up to a larger scope, one would assume that some garbage collection would pick that up 🤔
I don't know anything about COM objects, but it might be worth checking if there are explicit "close". "free" or "destroy" methods for this one?
I feel like there's a more pertinent keyword on the tip of my mental tongue, but I can't quite get there...

Hey, have you looked at this?
Possibly, you could call Release on it. Manage copies of references by using AddRef (But you probably won't have to create separate references. "Copying" the reference within AHK shouldn't change anything, I think, unless you do something fancy with dereferenced pointers/addresses. Otherwise, it all just points to the same thing. I think.)

I clearly don't know what I'm talking about, but I thought I'd throw my two cents in the ring, for better or for worse 😅

EDIT:
🤦‍♀️ yes, "release" is one of the keywords I was looking for, and you were already using it; you probably already know about the things discussed in the article. If so: Sorry to pollute the thread :/
:morebeard:

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 113 guests