Is there an "open folder" event Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
songdg
Posts: 512
Joined: 04 Oct 2017, 20:04

Is there an "open folder" event

Post by songdg » 25 Sep 2020, 23:22

I want to trigger an event when open a new folder or enter the sub_folder of an existing folder, in my case to read a txt file inside that folder automatically, is that possible or other ways to achieve the same purpose? Currently, I use a hotkey to do that.

User avatar
mikeyww
Posts: 26600
Joined: 09 Sep 2014, 18:38

Re: Is there an "open folder" event

Post by mikeyww » 26 Sep 2020, 06:12

What was your success method?

songdg
Posts: 512
Joined: 04 Oct 2017, 20:04

Re: Is there an "open folder" event

Post by songdg » 26 Sep 2020, 21:41

mikeyww wrote:
26 Sep 2020, 06:12
What was your success method?
I used the Explorer_GetActiveFolderPath() method.

User avatar
mikeyww
Posts: 26600
Joined: 09 Sep 2014, 18:38

Re: Is there an "open folder" event

Post by mikeyww » 27 Sep 2020, 06:55

It sounds like you have the folder path. Loop, Files can get you the files in that path.

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there an "open folder" event  Topic is solved

Post by teadrinker » 27 Sep 2020, 08:22

songdg wrote: I want to trigger an event when open a new folder or enter the sub_folder of an existing folder
Something like this:

Code: Select all

#Persistent
global EVENT_OBJECT_SHOW       := 0x8002
     , EVENT_OBJECT_NAMECHANGE := 0x800C

folderPath := "C:\Program Files"
WatchFolders := Func("IsMyFolderOpened").Bind(folderPath)

Hook := new WinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_NAMECHANGE, "HookProc", Object(WatchFolders))

IsMyFolderOpened(folderPath, hWnd) {
   openedFolderPath := GetFolderPath(hWnd)
   if InStr(openedFolderPath, folderPath . "\") || openedFolderPath = folderPath
      MsgBox, Folder %openedFolderPath% was opened
}

HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) {
   static OBJID_WINDOW := 0, CallBack, prevTime := 0
   (!CallBack && CallBack := Object(A_EventInfo))
   if (idObject != OBJID_WINDOW)
      Return
   if !(event = EVENT_OBJECT_SHOW || event = EVENT_OBJECT_NAMECHANGE)
      Return
   WinGetClass, winClass, ahk_id %hwnd%
   if (winClass != "CabinetWClass")
      Return
   if (A_TickCount - prevTime < 300)
      Return
   prevTime := A_TickCount
   CallBack.(hwnd)
}

GetFolderPath(hWnd := "") {
   (!hWnd && hWnd := WinExist("A"))
   WinGetClass, winClass, ahk_id %hWnd%
   if !(winClass ~="Progman|WorkerW|(Cabinet|Explore)WClass")
      Return
   
   if (winClass ~= "Progman|WorkerW")
      Return A_Desktop
   
   for window in ComObjCreate("Shell.Application").Windows {
      if (hWnd = window.HWND && dirPath := window.Document.Folder.Self.Path)
         break
   }
   Return dirPath
}

class WinEventHook
{
   __New(eventMin, eventMax, hookProc, eventInfo := 0, idProcess := 0, idThread := 0, dwFlags := 0) {
      this.pCallback := RegisterCallback(hookProc, "F",, eventInfo)
      this.hHook := DllCall("SetWinEventHook", "UInt", eventMin, "UInt", eventMax, "Ptr", 0, "Ptr", this.pCallback
                                             , "UInt", idProcess, "UInt", idThread, "UInt", dwFlags, "Ptr")
   }
   __Delete() {
      DllCall("UnhookWinEvent", "Ptr", this.hHook)
      DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
   }
}
If the Program Files folder or its subfolder is open, a message will appear.
Last edited by teadrinker on 27 Sep 2020, 08:46, edited 1 time in total.

User avatar
mikeyww
Posts: 26600
Joined: 09 Sep 2014, 18:38

Re: Is there an "open folder" event

Post by mikeyww » 27 Sep 2020, 08:35

Very nice!


songdg
Posts: 512
Joined: 04 Oct 2017, 20:04

Re: Is there an "open folder" event

Post by songdg » 27 Sep 2020, 09:02

teadrinker wrote:
27 Sep 2020, 08:22
songdg wrote: I want to trigger an event when open a new folder or enter the sub_folder of an existing folder
Something like this:

If the Program Files folder or its subfolder is open, a message will appear.
I want to give you :thumbup: ,thank you very much :bravo: !!!

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there an "open folder" event

Post by teadrinker » 27 Sep 2020, 09:49

You are welcome! :)

Falleau
Posts: 9
Joined: 26 Sep 2020, 13:40

Re: Is there an "open folder" event

Post by Falleau » 26 Feb 2021, 11:38

I tried teadrinker's snippet and it worked very nicely, but only when the folder is opened in file explorer. However, when I opened the folder from the desktop, the hook doesn't seem to trigger. Upon closer inspection, dirPath from GetFolderPath returned empty when any folder from the desktop is opened, causing openedFolderPath to be empty. Is there a way to fix this? Many thanks!

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there an "open folder" event

Post by teadrinker » 26 Feb 2021, 12:08

Can't reproduce the issue. Try running as admin.

Falleau
Posts: 9
Joined: 26 Sep 2020, 13:40

Re: Is there an "open folder" event

Post by Falleau » 26 Feb 2021, 14:10

I found the cause of the issue. It lies in this block of code:

Code: Select all

getStdOut(vTarget, vSize:="")
{
	Local
	DetectHiddenWindows, On
	vComSpec := A_ComSpec ? A_ComSpec : ComSpec
	Run, % vComSpec,, Hide, vPID
	WinWait, % "ahk_pid " vPID
	DllCall("kernel32\AttachConsole", "UInt",vPID)
	oShell := ComObjCreate("WScript.Shell")
	oExec := oShell.Exec(vTarget)
	vStdOut := ""
	if !(vSize = "")
		VarSetCapacity(vStdOut, vSize)
	while !oExec.StdOut.AtEndOfStream
		vStdOut := oExec.StdOut.ReadAll()
	DllCall("kernel32\FreeConsole")
	Process, Close, % vPID
	return vStdOut
}
...or anything similar in style, this kind of function grabs the output of the command prompt while it's completely hidden from the background. If I try to run that function globally, even once, such as:

Code: Select all

retrieveCommand = cmd.exe /c "powercfg.exe /list"
retrieveSchemes := getStdOut(retrieveCommand)
The folder watcher hook completely goes bonkers. Particularly, the GetFolderPath() function is affected. Do you have ideas why these two seem to clash with each other? Thank you.

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there an "open folder" event

Post by teadrinker » 26 Feb 2021, 15:10

Falleau wrote: Do you have ideas why these two seem to clash with each other?
No idea. But you can use this instead:

Code: Select all

retrieveCommand = powercfg.exe /list
MsgBox, % retrieveSchemes := CmdRet(retrieveCommand)

CmdRet(sCmd, callBackFuncObj := "", encoding := "")
{
   static flags := [HANDLE_FLAG_INHERIT := 0x1, CREATE_NO_WINDOW := 0x8000000], STARTF_USESTDHANDLES := 0x100
        
   (encoding = "" && encoding := "cp" . DllCall("GetOEMCP", "UInt"))
   DllCall("CreatePipe", "PtrP", hPipeRead, "PtrP", hPipeWrite, "Ptr", 0, "UInt", 0)
   DllCall("SetHandleInformation", "Ptr", hPipeWrite, "UInt", flags[1], "UInt", flags[1])
   
   VarSetCapacity(STARTUPINFO , siSize :=    A_PtrSize*4 + 4*8 + A_PtrSize*5, 0)
   NumPut(siSize              , STARTUPINFO)
   NumPut(STARTF_USESTDHANDLES, STARTUPINFO, A_PtrSize*4 + 4*7)
   NumPut(hPipeWrite          , STARTUPINFO, A_PtrSize*4 + 4*8 + A_PtrSize*3)
   NumPut(hPipeWrite          , STARTUPINFO, A_PtrSize*4 + 4*8 + A_PtrSize*4)
   
   VarSetCapacity(PROCESS_INFORMATION, A_PtrSize*2 + 4*2, 0)

   if !DllCall("CreateProcess", "Ptr", 0, "Str", sCmd, "Ptr", 0, "Ptr", 0, "UInt", true, "UInt", flags[2]
                              , "Ptr", 0, "Ptr", 0, "Ptr", &STARTUPINFO, "Ptr", &PROCESS_INFORMATION)
   {
      DllCall("CloseHandle", "Ptr", hPipeRead)
      DllCall("CloseHandle", "Ptr", hPipeWrite)
      throw "CreateProcess is failed"
   }
   DllCall("CloseHandle", "Ptr", hPipeWrite)
   VarSetCapacity(sTemp, 4096), nSize := 0
   while DllCall("ReadFile", "Ptr", hPipeRead, "Ptr", &sTemp, "UInt", 4096, "UIntP", nSize, "UInt", 0) {
      sOutput .= stdOut := StrGet(&sTemp, nSize, encoding)
      ( callBackFuncObj && callBackFuncObj.Call(stdOut) )
   }
   DllCall("CloseHandle", "Ptr", NumGet(PROCESS_INFORMATION))
   DllCall("CloseHandle", "Ptr", NumGet(PROCESS_INFORMATION, A_PtrSize))
   DllCall("CloseHandle", "Ptr", hPipeRead)
   Return sOutput
}

Falleau
Posts: 9
Joined: 26 Sep 2020, 13:40

Re: Is there an "open folder" event

Post by Falleau » 26 Feb 2021, 23:08

Awesome, that approach does not conflict with the hook at all. Thank you so much! :D

superpeter
Posts: 115
Joined: 18 Dec 2020, 05:17

Re: Is there an "open folder" event

Post by superpeter » 27 Feb 2021, 01:11

That is so awesome, thanks teadrinker! I can keep a log of when each subfolder was opened in the main folder.

Just wondering, is it possible to similarly check if a file (say, a text file or any kind of file) is opened in a certain folder? Thx

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there an "open folder" event

Post by teadrinker » 27 Feb 2021, 07:44

superpeter wrote: if a file (say, a text file or any kind of file) is opened in a certain folder?
What do you mean by this? A file from a certain folder is open in any application, or an opened folder contains a certain file?

superpeter
Posts: 115
Joined: 18 Dec 2020, 05:17

Re: Is there an "open folder" event

Post by superpeter » 27 Feb 2021, 12:14

Sorry, I meant if "A file from a certain folder is opened." For example, if "somefile.txt" (from a certain folder) is opened, a Msgbox would pop up. Or if "anyfile.*" (any type of file) is opened from a certain folder.

For "if a folder contains a certain file," I think I can use If FileExist. :)

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there an "open folder" event

Post by teadrinker » 27 Feb 2021, 12:47

It very depends on application which open a file. I don't know any reliable way to find out what the file is open with notepad.

superpeter
Posts: 115
Joined: 18 Dec 2020, 05:17

Re: Is there an "open folder" event

Post by superpeter » 27 Feb 2021, 12:59

I tested with the following code and it seems to work!

Code: Select all

settimer, check, 1000

var := "test copy"
check:
loop
{
IfWinExist, %var% - Notepad
 msgbox, The file %var% has been opened
}
return 

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there an "open folder" event

Post by teadrinker » 27 Feb 2021, 13:08

But where is a folder path there?

Post Reply

Return to “Ask for Help (v1)”