Re: WatchFolder() - updated on 2021-10-14
Posted: 20 Apr 2022, 01:00
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?
Let's help each other out
https://www.autohotkey.com/boards/
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
}
}
}
}
Code: Select all
If RegExMatch(name, "Humpty_Dumpty|Pudding|chocolate")
{
WatchFolder("**PAUSE", True)
<unpack code>
WatchFolder("**PAUSE", False)
}
Code: Select all
If RegExMatch(name, "(Humpty_Dumpty|Pudding|chocolate).*\.rar$") {
<unpack code>
}
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"
}
...
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
@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.
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
}
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
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.
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
}