WatchFolder() - updated on 2021-10-14
Re: WatchFolder() - updated on 2021-10-14
hi there, is it possible to trigger action after folder change happens? Or for example is it possible to trigger an action when .xls is added to watched folder?
Re: WatchFolder() - updated on 2021-10-14
That is the entire purpose of the function Example, note the values of what is what
Code: Select all
#Persistent
#SingleInstance, force
SetWorkingDir, %A_ScriptDir%
#include WatchFolder.ahk ; copy/download the code from the first post, save it as WatchFolder.ahk
; ReadDirectoryChangesW msdn.microsoft.com/en-us/library/aa365465(v=vs.85).aspx
; FILE_NOTIFY_CHANGE_FILE_NAME = 1 (0x00000001) : Notify about renaming, creating, or deleting a file.
; FILE_NOTIFY_CHANGE_DIR_NAME = 2 (0x00000002) : Notify about creating or deleting a directory.
; FILE_NOTIFY_CHANGE_ATTRIBUTES = 4 (0x00000004) : Notify about attribute changes.
; FILE_NOTIFY_CHANGE_SIZE = 8 (0x00000008) : Notify about any file-size change.
; FILE_NOTIFY_CHANGE_LAST_WRITE = 16 (0x00000010) : Notify about any change to the last write-time of files.
; FILE_NOTIFY_CHANGE_LAST_ACCESS = 32 (0x00000020) : Notify about any change to the last access time of files.
; FILE_NOTIFY_CHANGE_CREATION = 64 (0x00000040) : Notify about any change to the creation time of files.
; FILE_NOTIFY_CHANGE_SECURITY = 256 (0x00000100) : Notify about any security-descriptor change.
; FILE_NOTIFY_INFORMATION msdn.microsoft.com/en-us/library/aa364391(v=vs.85).aspx
; FILE_ACTION_ADDED = 1 (0x00000001) : The file was added to the directory.
; FILE_ACTION_REMOVED = 2 (0x00000002) : The file was removed from the directory.
; FILE_ACTION_MODIFIED = 3 (0x00000003) : The file was modified.
; FILE_ACTION_RENAMED = 4 (0x00000004) : The file was renamed (not defined by Microsoft).
; FILE_ACTION_RENAMED_OLD_NAME = 4 (0x00000004) : The file was renamed and this is the old name.
; FILE_ACTION_RENAMED_NEW_NAME = 5 (0x00000005) : The file was renamed and this is the new name.
; GetOverlappedResult msdn.microsoft.com/en-us/library/ms683209(v=vs.85).aspx
; CreateFile msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx
; FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
; FILE_FLAG_OVERLAPPED = 0x40000000
WatchFolder("path-to-your-folder", "ReportFunction") ; change the path of course
ReportFunction(Directory, Changes)
{
For Each, Change In Changes
{
Action := Change.Action
Name := Change.Name
; -------------------------------------------------------------------------------------------------------------------------
; Action 1 (added) = File gets added in the watched folder
If (Action = 1)
{
If RegExMatch(name,"i)\.xlsx?$") check if we have an excel file (ending in xls or xlsx)
{
; if excel file do something
MsgBox % name
}
}
}
}
Re: WatchFolder() - updated on 2021-10-14
Thank you just me for your wonderful function.
It works as expected, but there is one problem. I'd love to get some advice on how to resolve this if you'd like:)
WatchFolder is used to convert a RAR file with a specified filename with date to uncompressed ZIP.
The zip software I use generates a .tmp file with the same filename in the same directory as the file being processed.
This causes the unpacking process to be performed three times.
Create file
Pudding.rar → 1 Action
Pudding.tmp → 2 Action(but, Nothing happens because the file is in use.)
Pudding.zip → 3 Action(but, Unpacked, so nothing happens.)
Even if PAUSE is built in, it will be processed multiple times.
Is there any good solution?
It works as expected, but there is one problem. I'd love to get some advice on how to resolve this if you'd like:)
WatchFolder is used to convert a RAR file with a specified filename with date to uncompressed ZIP.
The zip software I use generates a .tmp file with the same filename in the same directory as the file being processed.
This causes the unpacking process to be performed three times.
Create file
Pudding.rar → 1 Action
Pudding.tmp → 2 Action(but, Nothing happens because the file is in use.)
Pudding.zip → 3 Action(but, Unpacked, so nothing happens.)
Even if PAUSE is built in, it will be processed multiple times.
Code: Select all
If RegExMatch(name, "Humpty_Dumpty|Pudding|chocolate")
{
WatchFolder("**PAUSE", True)
<unpack code>
WatchFolder("**PAUSE", False)
}
Re: WatchFolder() - updated on 2021-10-14
Code: Select all
If RegExMatch(name, "(Humpty_Dumpty|Pudding|chocolate).*\.rar$") {
<unpack code>
}
Re: WatchFolder() - updated on 2021-10-14
Thanks for getting back to me so quickly!
It worked perfectly.
It was a regular expression problem, I understand.
It worked perfectly.
It was a regular expression problem, I understand.
Re: WatchFolder() - updated on 2021-10-14
Just reporting that the function does not detect any changes for directories on a network drive in my environment, Windows 10 64bit with AutoHotkeyU64 1.1.34.03.
Re: WatchFolder() - updated on 2021-10-14
@just me I'm wondering if you can implement the ability to accept class methods for the callback function like what SetTimer does.
From the manual of SetTimer,
Code: Select all
oWatchFolder := new TestWatchFolder(A_ScriptDir)
class TestWatchFolder {
sPathDir := ""
func := {}
__New(sPathDir) {
this.sPathDir := sPathDir
this.func := ObjBindMethod(this, "watch")
WatchFolder(sPathDir, this.func, true)
}
watch(sPathFolder, oChanges) {
; do something
}
}
Code: Select all
class SecondCounter {
__New() {
this.interval := 1000
this.count := 0
; Tick() has an implicit parameter "this" which is a reference to
; the object, so we need to create a function which encapsulates
; "this" and the method to call:
this.timer := ObjBindMethod(this, "Tick")
}
Start() {
; Known limitation: SetTimer requires a plain variable reference.
timer := this.timer
SetTimer % timer, % this.interval
ToolTip % "Counter started"
}
...
Re: WatchFolder() - updated on 2021-10-14
I dont really know much of Autohotkey outside of Sendinput and sleep. I was able to put this together from reading this thread. Here is my code so far:
I am struggling with File modified action, Any autohotkey code I set to execute upon a file being modified is run twice. In the above example Run, Notepad is executed twice, so two notepad windows open. Its the same if I get a .Url link to open. It will be open twice too.
Any ideas what I could be doing wrong?
PS: Watchfolder function is saved in Documents\Autohotkey\Lib folder and I have made no changes to it, it is as I downloaded it.
Code: Select all
#Persistent
#Include, <WatchFolder>
WatchFolder("C:\Users\...\Downloads", "ReportFunction", false, 1 | 2 | 4 | 8 |16 | 32 | 64 | 256)
Return
ReportFunction(Directory, Changes) {
For Each, Change In Changes {
Action := Change.Action
Name := Change.Name
If (Action = 3)
Run, Notepad
Return
}
}
Esc::ExitApp
Any ideas what I could be doing wrong?
PS: Watchfolder function is saved in Documents\Autohotkey\Lib folder and I have made no changes to it, it is as I downloaded it.
Re: WatchFolder() - updated on 2021-10-14
Only two files will be processed for more than two files.
Are there any best practices for loop processing to handle all files?
Are there any best practices for loop processing to handle all files?
Re: WatchFolder() - updated on 2021-10-14
@tester: I'm not interested in doing it, sorry.tester wrote:@just me I'm wondering if you can implement the ability to accept class methods for the callback function like what SetTimer does.
@Netmano: What kind of modifications do you do you specify to be watched?Netmano wrote:I am struggling with File modified action, Any autohotkey code I set to execute upon a file being modified is run twice.
@dostroll: Show your code, please.dostroll wrote:Only two files will be processed for more than two files.
Re: WatchFolder() - updated on 2021-10-14
I solved it by accident.
Sorry for the inconvenience...
It's because I typed "Return". (I don't understand why there is a problem with Return.)
Sorry for the inconvenience...
It's because I typed "Return". (I don't understand why there is a problem with Return.)
Code: Select all
; Action 1 (added) = File gets added in the watched folder
If (vAction = 1)
{
If RegExMatch(Name, "(chocolate|cocoa|sup).*\.(rar|cbz)$")
{
Sleep, 500
Run, rename.exe "%vName%"
tooltip_func("● Unzip complete", 950)
; Return
}
Re: WatchFolder() - updated on 2021-10-14
@just me
Hey, thanks for getting back to me.
I want to be notified only if the files contents has been edited
Hey, thanks for getting back to me.
I want to be notified only if the files contents has been edited
Re: WatchFolder() - updated on 2021-10-14
@just me On my PC WatchFolder() (both the v1 and v2 version) calls the UserFunc twice for each change, I think that's the issue @Netmano is reporting too. I tested with the WatchFolder_sample.ahk script.
Re: WatchFolder() - updated on 2021-10-14
Try to set the Watch parameter to 0x10 (FILE_NOTIFY_CHANGE_LAST_WRITE) in this case.Netmano wrote:I want to be notified only if the files contents has been edited
Re: WatchFolder() - updated on 2021-10-14
8 second clip that shows the "calls the UserFunc twice for each change" issue
https://i.imgur.com/509vRk5.mp4
https://i.imgur.com/509vRk5.mp4
Re: WatchFolder() - updated on 2021-10-14
@neogna2:
I cannot reproduce the behaviour here. I'm getting only one call for the UserFunc.
I cannot reproduce the behaviour here. I'm getting only one call for the UserFunc.
Re: WatchFolder() - updated on 2021-10-14
Hm, my PC runs Win10 (august 2022 updated) and I get the UserFunc called twice issue with v1 U32 and U64 (and v2.beta7 for v2 WatchFolder) and when using several different apps to trigger the file/folder change. Perhaps @Netmano (and others) can reply and say if they have exactly the same issue as in my clip above. In order to pin down if this is a WatchFolder code issue or more of a neogna2's PC issue.
Re: WatchFolder() - updated on 2021-10-14
Seems there's no perfect solution among those StackOverflow answers? Here's a quick attempt. If previous call was < 100 ms ago and if the file and type of change is the same as in the previous call then skip that item this call. Possible problem: these extra checks might slow things down or cause other problems if a ton of files are monitored with lots of changes frequently?
Code: Select all
MyUserFunc(Folder, Changes) {
Static Actions := ["1 (added)", "2 (removed)", "3 (modified)", "4 (renamed)"]
static PrevTickCount := 0
static PrevChanges := []
TickCount := A_TickCount
GuiControl, -ReDraw, LV
For Each, Change In Changes
{
if (TickCount - OldTickCount) < 100
for Each, OldChange In OldChanges
if Change.Action = OldChange.Action && Change.Name = OldChange.Name
Continue, 2
LV_Modify(LV_Add("", TickCount, Folder, Actions[Change.Action], Change.Name, Change.IsDir, Change.OldName, ""), "Vis")
}
OldChanges := Changes
OldTickCount := TickCount
Loop, % LV_GetCount("Columns")
LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +Redraw, LV
}
Re: WatchFolder() - updated on 2021-10-14
Hi @neogna2,
because I don't use Notepad++ I tested using Notepad. The UserFunc is called only once if you save the file with Notepad. When I tried the same with my favourite editor PSPad, then function was called twice here too. So the number of calls seems to depend on the application writing the file.
because I don't use Notepad++ I tested using Notepad. The UserFunc is called only once if you save the file with Notepad. When I tried the same with my favourite editor PSPad, then function was called twice here too. So the number of calls seems to depend on the application writing the file.
Return to “Scripts and Functions (v1)”
Who is online
Users browsing this forum: No registered users and 73 guests