AutoHotkey Community

It is currently May 26th, 2012, 1:30 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 97 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7  Next
Author Message
 Post subject:
PostPosted: May 25th, 2008, 7:13 pm 
Offline

Joined: April 15th, 2008, 9:34 pm
Posts: 44
Hi:

Just noticed this script and it works great for a task I have. But, as another user mentioned, for each file it gives more than one notification in the listbox. Any ideas on where I would look (what function) in order to attempt to fix this?

BTW, I am using the code from the first posting in this topic.

Thanks.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 25th, 2008, 2:44 pm 
Offline

Joined: June 25th, 2008, 2:31 pm
Posts: 25
I want to change this script to fit my work needs, but am having trouble understanding some of the syntax. I'm sorta new to AHK and have been unable to find anything on it in the help file or here.

Code:
Loop %WatchFolder%, 1 ; gets all files & folders within WatchFolder
      WatchFolder := A_LoopFileLongPath ; ??? I don't understand the purpose of this statement...overwriting the WatchFolder variable/label a bunch...
DllCall( "shlwapi\PathAddBackslashA", UInt,&Watchfolder ) ; Adds a backslash to the end of WatchFolder


...


Code:
 WatchFolder:


I've tried looking at labels & g-labels, but they don't seem to match this syntax. I think its calling the WatchFolder label/subroutine for each file/folder in there, but I don't quite get the specifics - especially the whole assigning a value to WatchFolder. Is there a link to somewhere that explains this syntax?

Thanks,
jms


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 25th, 2008, 2:56 pm 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Just applies a cosmestic effect on the path:

Code:
MsgBox, %A_Temp%

Loop, %A_Temp%,1
  Watchfolder := A_LoopFileLongPath
 
Msgbox, % WatchFolder


The above code transforms a Shortpath to long path

Code:
Loop %WatchFolder%, 1 ; gets all files & folders within WatchFolder


The above line will only loop once since the path does not contain wildcard.

:)

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 25th, 2008, 3:13 pm 
Offline

Joined: June 25th, 2008, 2:31 pm
Posts: 25
What about:
Code:
WatchFolder: ; What is this syntax?

  GuiControlGet, WatchFolder
  GuiControlGet, WatchSubDirs
; ...

Is this a label/subroutine, and if it is, where/how is it called? How does this not get confused with the WatchFolder variable in the 1st set of code I posted or are they related?

(I like using "/")

Thanks again,
jms


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 25th, 2008, 3:31 pm 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
joemoeschmoe wrote:
What about:
Code:
WatchFolder: ; What is this syntax?

  GuiControlGet, WatchFolder
  GuiControlGet, WatchSubDirs
; ...

Is this a label/subroutine, and if it is, where/how is it called?


WatchFolder is a variable
WatchFolder: is a subroutine

WatchFolder is triggered from a timer when Start/Stop button is clicked.
Start/Stop is associated with gLabel StartStop:

:)

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 31st, 2008, 10:45 pm 
Offline

Joined: April 9th, 2008, 11:46 pm
Posts: 14
Lexikos wrote:
Select folders one at a time. It needs cleaning up, but hopefully you get the point. "Stop" is disabled and directories cannot be removed. (I'll leave it to someone else to add these features.)

I'm experimenting your script these days. I am not skilled at all with dll call, but what is it needed to stop monitoring?
In the very first version of the script, three calls are used:
Code:
  DllCall( "CloseHandle", UInt,hDir )
  DllCall( "TerminateThread", UInt,hThread, UInt,0 )
  DllCall( "CloseHandle", UInt,hThread )

In your version, the OpenThread call is not used so I suppose that the last two calls are not needed. What about the first? Need I to use it?
Many thanks.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 9th, 2008, 7:37 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Many thanks for this script SKAN, it is really great :D

Many thanks Lexikos for your version as well, it is exactly what I was looking for (implemented in AutoHotFile)

Lexikos wrote:
"Stop" is disabled and directories cannot be removed. (I'll leave it to someone else to add these features.)

Any chance you could add these features, would be much appreciated.
If not, can you please give your ideas how to and somebody could try to implement. :)

EDIT: Would this be enough to stop watching?
Code:
Loop %DirIdx%
   {
      DllCall( "CloseHandle", UInt,Dir%A_Index% )
      DllCall( "TerminateThread", UInt,NumGet(Dir%A_Index%Overlapped, 16), UInt,0 )
      DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) ) 
   }

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 28th, 2008, 9:27 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
Sorry caterva, I must've missed your post.

HotKeyIt, do not call TerminateThread - an event handle is not a thread handle. You must also reset DirIdx to blank or 0, otherwise the script will pass the old (now closed) handles to MsgWaitForMultipleObjectsEx.

You could also free the contents of Dir%DirIdx%* and DirEvent, but they may be automatically reused, so it is not critical.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 28th, 2008, 3:20 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Many thanks Lexikos, will try to get it working.

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 29th, 2008, 12:25 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Thanks a lot Lexikos, I think it is working now.

I have added a few edit controls for selection of several folders.
You can cancel FileSelectFolder to empty the corresponding edit control.
When you select several folders in same edit controls while you are watching folders it will add a directory to be watched for but not remove the one before!

Lexikos, can you confirm whether stop is correct?

Can anybody confirm it is working fine?

Code:
#Persistent
SetBatchLines, -1
Process, Priority,, High
OnExit, ShutApp
Menu, Tray, Icon, Shell32.dll, 4
Menu, Tray, Tip , FolderSpy

WatchFolder  := A_Temp . "orary Internet Files"
WatchSubDirs := True

Loop %WatchFolder%, 1
      WatchFolder := A_LoopFileLongPath
DllCall( "shlwapi\PathAddBackslashA", UInt,&Watchfolder )

CBA_ReadDir := RegisterCallback("ReadDirectoryChanges")

; FILE_NOTIFY_INFORMATION : http://msdn2.microsoft.com/en-us/library/aa364391.aspx

SizeOf_FNI := ( 64KB := 1024 * 64 )
; VarSetCapacity( FILE_NOTIFY_INFORMATION, SizeOf_FNI, 0 )
; PointerFNI := &FILE_NOTIFY_INFORMATION

Gui, Margin, 5, 5
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder1, %WatchFolder%
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton1, ...
Gui, Add, Text     , x+40                                      , S
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder2,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton2, ...
Gui, Add, Text     , x+40                                      , U
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder3,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton3, ...
Gui, Add, Text     , x+40                                      , B
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder4,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton4, ...
Gui, Add, CheckBox , x+22      h18 vWatchSubDirs Checked 0x20,
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder5,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton5, ...
Gui, Add, Text     , x+40                                      , F
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder6,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton6, ...
Gui, Add, Text     , x+40                                      , O
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder7,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton7, ...
Gui, Add, Text     , x+40                                      , L
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder8,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton8, ...
Gui, Add, Text     , x+40                                      , D
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder9,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton9, ...
Gui, Add, Text     , x+40                                      , E
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder10,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton10, ...
Gui, Add, Text     , x+40                                      , R
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder11,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton11, ...
Gui, Add, Text     , x+40                                      , S
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder12,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton12, ...
Gui, Add, Button   , x+5       h18 gDeleteSelection vDeleteSelection, DELETE ALL

Gui, Add, ListView , x5   w700 h380 +Grid vSpyLV
                   , Time|Event|File/Folder Name|Size-KB|TimeStamp [Mod]|Attrib
Gui, Add, Button   , x550  w64  h22 +Default vClear gClearListView, Clear
Gui, Add, Button   , x+10  w64  h22 +Default vStartStop gStartStop, Start

LV_ModifyCol( 1, "54" )
LV_ModifyCol( 2, "75  Center " )
LV_ModifyCol( 3, "327        " )
LV_ModifyCol( 4, "55  Integer" )
LV_ModifyCol( 5, "120        " )
LV_ModifyCol( 6, "46         " )

Gui, Add, StatusBar
SB_SetParts( 100, 500 )
GuiControl, Focus, StartStop
Gui, Show, , FolderSpy v0.97X

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
Return ;                                                  [| End of Auto-execute section |]
;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -


WatchFolder:

  ReadDirectoryChanges()

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
DeleteSelection:
If Watch
 Gosub, StartStop
Loop 12
 GuiControl,,WatchFolder%A_Index%
Return

SelectFolder:
    FileSelectFolder, SelFolder, *%WatchFolder%, , Select Watch Folder
   If ( SelFolder = "" )
   {
      GuiControl,,% "WatchFolder" . SubStr(A_GuiControl, 13)
      Return
    }
   If !(StrLen(SelFolder) = 3 and SubStr(SelFolder, 0) = "\")
   {
      Loop %SelFolder%, 1
      WatchFolder := A_LoopFileLongPath
      DllCall( "shlwapi\PathAddBackslashA", UInt,&Watchfolder )
   }
   else
      WatchFolder := SelFolder
   GuiControl,,% "WatchFolder" . SubStr(A_GuiControl, 13), %WatchFolder%
   GuiControl, Focus, StartStop
    SelFolder =
    BeginWatchingDirectory(WatchFolder, WatchSubDirs)
Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

StartStop:

Watch := !Watch
  If ( Watch ) {
                Loop 12
                {
                  GuiControlGet, WatchFolder, , WatchFolder%A_Index%
                  If (WatchFolder != "")
                  {
                    ;MsgBox % WatchFolder
                    BeginWatchingDirectory(WatchFolder, WatchSubDirs)
                  }
                }
            GuiControl,, StartStop, Stop   
            SetTimer, WatchFolder, 10
}  Else      {
            Loop %DirIdx%
            {
               Dir%A_Index%         =
               Dir%A_Index%Path     =
               Dir%A_Index%Subdirs  =
               Dir%A_Index%FNI      =
               Dir%A_Index%Overlapped=
               DllCall( "CloseHandle", UInt,Dir%A_Index% )
               DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) ) 
            }
            DirIdx= 0
            SetTimer, WatchFolder, Off
            GuiControl,, StartStop, Start
  }

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

BeginWatchingDirectory(WatchFolder, WatchSubDirs=true)
{
    local hDir, hEvent
    DirIdx += 1
   
    ; CreateFile: http://msdn2.microsoft.com/en-us/library/aa914735.aspx

    hDir := DllCall( "CreateFile"
                 , Str  , WatchFolder
                 , UInt , ( FILE_LIST_DIRECTORY := 0x1 )
                 , UInt , ( FILE_SHARE_READ     := 0x1 )
                        | ( FILE_SHARE_WRITE    := 0x2 )
                        | ( FILE_SHARE_DELETE   := 0x4 )
                 , UInt , 0
                 , UInt , ( OPEN_EXISTING := 0x3 )
                 , UInt , ( FILE_FLAG_BACKUP_SEMANTICS := 0x2000000  )
                        | ( FILE_FLAG_OVERLAPPED       := 0x40000000 )
                 , UInt , 0 )
   
    Dir%DirIdx%         := hDir
    Dir%DirIdx%Path     := WatchFolder
    Dir%DirIdx%Subdirs  := WatchSubDirs
    VarSetCapacity( Dir%DirIdx%FNI, SizeOf_FNI )
    VarSetCapacity( Dir%DirIdx%Overlapped, 20, 0 )
    hEvent := DllCall( "CreateEvent", UInt,0, Int,true, Int,false, UInt,0 )
    NumPut( hEvent, Dir%DirIdx%Overlapped, 16 )
   
    ; Maintain array of event handles to wait on.
    if ( VarSetCapacity(DirEvents) < DirIdx*4 )
    {   ; Expand by 16 directories (64 bytes) at a time.
        VarSetCapacity(DirEvents, DirIdx*4 + 60)
        ; Copy all previous event handles.
        Loop %DirIdx%
            NumPut( NumGet( Dir%A_Index%Overlapped, 16 ), DirEvents, A_Index*4-4 )
    }
    NumPut( hEvent, DirEvents, DirIdx*4-4 )
   
    DllCall( "ReadDirectoryChangesW"  ; http://msdn2.microsoft.com/en-us/library/aa365465.aspx
                , UInt , hDir
                , UInt , &Dir%DirIdx%FNI
                , UInt , SizeOf_FNI
                , UInt , WatchSubDirs
                , UInt , ( FILE_NOTIFY_CHANGE_FILE_NAME   := 0x1   )
                       | ( FILE_NOTIFY_CHANGE_DIR_NAME    := 0x2   )
                       | ( FILE_NOTIFY_CHANGE_ATTRIBUTES  := 0x4   )
                       | ( FILE_NOTIFY_CHANGE_SIZE        := 0x8   )
                       | ( FILE_NOTIFY_CHANGE_LAST_WRITE  := 0x10  )
                       | ( FILE_NOTIFY_CHANGE_LAST_ACCESS := 0x20  )
                       | ( FILE_NOTIFY_CHANGE_CREATION    := 0x40  )
                       | ( FILE_NOTIFY_CHANGE_SECURITY    := 0x100 )
                , UInt , 0
                , UInt , &Dir%DirIdx%Overlapped
                , UInt , 0  )
}

; Handles one directory at a time.
; Returns non-zero if a change was detected.
; Returns zero if it timed out or a window message was received.
ReadDirectoryChanges(Timeout=-1)
{
    local hDir, r
    ; Wait for any event object to be signaled or a window message to be received.
    r := DllCall("MsgWaitForMultipleObjectsEx", UInt, DirIdx, UInt, &DirEvents
                                            , UInt, Timeout, UInt, 0x4FF, UInt, 0x6)
    if (r >= 0 && r < DirIdx) ; WAIT_OBJECT_*
    {
        r += 1
        ; At least one event object was signaled. Decode the FNI for this event.
        ; If more than one event object was signaled, this func must be called again.
        WatchFolder := Dir%r%Path
        PointerFNI := &Dir%r%FNI
        nReadLen := 0
        DllCall( "GetOverlappedResult", UInt, hDir
                    , UInt, &Dir%r%Overlapped, UIntP, nReadLen, Int, true )
        gosub Decode_FILE_NOTIFY_INFORMATION
       
        ; Reset the event and call ReadDirectoryChangesW in async mode again.
        DllCall( "ResetEvent", UInt,NumGet( Dir%r%Overlapped, 16 ) )
        DllCall( "ReadDirectoryChangesW"
                , UInt , Dir%r%
                , UInt , &Dir%r%FNI
                , UInt , SizeOf_FNI
                , UInt , Dir%r%WatchSubDirs
                , UInt , ( FILE_NOTIFY_CHANGE_FILE_NAME   := 0x1   )
                       | ( FILE_NOTIFY_CHANGE_DIR_NAME    := 0x2   )
                       | ( FILE_NOTIFY_CHANGE_ATTRIBUTES  := 0x4   )
                       | ( FILE_NOTIFY_CHANGE_SIZE        := 0x8   )
                       | ( FILE_NOTIFY_CHANGE_LAST_WRITE  := 0x10  )
                       | ( FILE_NOTIFY_CHANGE_LAST_ACCESS := 0x20  )
                       | ( FILE_NOTIFY_CHANGE_CREATION    := 0x40  )
                       | ( FILE_NOTIFY_CHANGE_SECURITY    := 0x100 )
                , UInt , 0
                , UInt , &Dir%r%Overlapped
                , UInt , 0  )
        return r
    }
    return 0
}

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -


Decode_FILE_NOTIFY_INFORMATION:

;   PointerFNI := &FILE_NOTIFY_INFORMATION

  Loop {

    NextEntry   := NumGet( PointerFNI + 0  )
    Action      := NumGet( PointerFNI + 4  )
    FileNameLen := NumGet( PointerFNI + 8  )
    FileNamePtr :=       ( PointerFNI + 12 )


    If ( Action = 0x1 )                            ; FILE_ACTION_ADDED   
       Event := "New File"

    If ( Action = 0x2 )                            ; FILE_ACTION_REMOVED 
       Event := "Deleted"

    If ( Action = 0x3 )                            ; FILE_ACTION_MODIFIED 
       Event := "Modified"

    If ( Action = 0x4 )                            ; FILE_ACTION_RENAMED_OLD_NAME
       Event := "Renamed Fm"

    If ( Action = 0x5 )                            ; FILE_ACTION_RENAMED_NEW_NAME
       Event := "Renamed To"

    VarSetCapacity( FileNameANSI, FileNameLen )
    DllCall( "WideCharToMultiByte", UInt,0, UInt,0, UInt,FileNamePtr, UInt
           , FileNameLen,  Str,FileNameANSI, UInt,FileNameLen, UInt,0, UInt,0 )

    File := SubStr( FileNameANSI, 1, FileNameLen/2 )
    FullPath := WatchFolder . "\" . File
    FileGetAttrib, Attr, %FullPath%
    FormatTime, Time  , %A_Now%, HH:mm:ss

    If ( FileExist( FullPath ) = "" )
     {
       LV_Insert( 1, "", Time, Event, FullPath )
       Sb_SetText( "`t" LV_GetCount() )
     }
    Else
    Loop %FullPath%
     {
       FormatTime, TStamp, %A_LoopFileTimeModified%, yyyy-MM-dd  HH:mm:ss
       LV_Insert( 1, "", Time, Event, FullPath, A_LoopFileSizeKB, TStamp, A_LoopFileAttrib )
       Sb_SetText( "`t" LV_GetCount() )
     }

    If (!NextEntry or NextEntry = 4129024)
       Break
    Else
       PointerFNI := PointerFNI + NextEntry
  }

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

GuiClose:
ShutApp:

  DllCall( "CloseHandle", UInt,hDir )
  ExitApp

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

ClearListView:

 LV_Delete() , Sb_SetText("")

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Last edited by HotKeyIt on June 11th, 2009, 1:27 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 1st, 2008, 8:06 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
I have changed a few things and hopefully fixed same as well, double entries should not be shown anymore.

Code:
#Persistent
SetBatchLines, -1
Process, Priority,, High
OnExit, ShutApp
Menu, Tray, Icon, Shell32.dll, 4
Menu, Tray, Tip , FolderSpy

WatchFolder  := A_Temp . "orary Internet Files"
WatchSubDirs := True

Loop %WatchFolder%, 1
      WatchFolder := A_LoopFileLongPath
DllCall( "shlwapi\PathAddBackslashA", UInt,&Watchfolder )

CBA_ReadDir := RegisterCallback("ReadDirectoryChanges")

; FILE_NOTIFY_INFORMATION : http://msdn2.microsoft.com/en-us/library/aa364391.aspx

SizeOf_FNI := ( 64KB := 1024 * 64 )
; VarSetCapacity( FILE_NOTIFY_INFORMATION, SizeOf_FNI, 0 )
; PointerFNI := &FILE_NOTIFY_INFORMATION

Gui, Margin, 5, 5
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder1, %WatchFolder%
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton1, ...
Gui, Add, Text     , x+40                                      , S
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder2,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton2, ...
Gui, Add, Text     , x+40                                      , U
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder3,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton3, ...
Gui, Add, Text     , x+40                                      , B
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder4,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton4, ...
Gui, Add, CheckBox , x+22      h18 vWatchSubDirs Checked 0x20,
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder5,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton5, ...
Gui, Add, Text     , x+40                                      , F
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder6,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton6, ...
Gui, Add, Text     , x+40                                      , O
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder7,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton7, ...
Gui, Add, Text     , x+40                                      , L
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder8,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton8, ...
Gui, Add, Text     , x+40                                      , D
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder9,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton9, ...
Gui, Add, Text     , x+40                                      , E
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder10,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton10, ...
Gui, Add, Text     , x+40                                      , R
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder11,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton11, ...
Gui, Add, Text     , x+40                                      , S
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder12,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton12, ...
Gui, Add, Button   , x+5       h18 gDeleteSelection vDeleteSelection, DELETE ALL

Gui, Add, ListView , x5   w700 h380 +Grid vSpyLV
                   , Time|Event|File/Folder Name|Size-KB|TimeStamp [Mod]|Attrib
Gui, Add, Button   , x550  w64  h22 +Default vClear gClearListView, Clear
Gui, Add, Button   , x+10  w64  h22 +Default vStartStop gStartStop, Start

LV_ModifyCol( 1, "54" )
LV_ModifyCol( 2, "75  Center " )
LV_ModifyCol( 3, "327        " )
LV_ModifyCol( 4, "55  Integer" )
LV_ModifyCol( 5, "120        " )
LV_ModifyCol( 6, "46         " )

Gui, Add, StatusBar
SB_SetParts( 100, 500 )
GuiControl, Focus, StartStop
Gui, Show, , FolderSpy v0.97X

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
Return ;                                                  [| End of Auto-execute section |]
;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -


WatchFolder:

  ReadDirectoryChanges()

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
DeleteSelection:
If Watch
 Gosub, StartStop
Loop 12
 GuiControl,,WatchFolder%A_Index%
Return

SelectFolder:
    FileSelectFolder, SelFolder, *%WatchFolder%, 2, Select Watch Folder
   If ( SelFolder = "" )
   {
      GuiControl,,% "WatchFolder" . SubStr(A_GuiControl, 13)
      Return
    }
   If !(StrLen(SelFolder) = 3 and SubStr(SelFolder, 0) = "\")
   {
      Loop %SelFolder%, 1
      WatchFolder := A_LoopFileLongPath
      DllCall( "shlwapi\PathAddBackslashA", UInt,&Watchfolder )
   }
   else
      WatchFolder := SelFolder
   GuiControl,,% "WatchFolder" . SubStr(A_GuiControl, 13), %WatchFolder%
   GuiControl, Focus, StartStop
    SelFolder =
   If ( Watch )
    BeginWatchingDirectory(WatchFolder, WatchSubDirs)
Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

StartStop:

Watch := !Watch
  If ( Watch ) {
                DirIdx= 0
                Loop 12
                {
                  GuiControlGet, WatchFolder, , WatchFolder%A_Index%
                  If (WatchFolder != "")
                  {
                    BeginWatchingDirectory(WatchFolder, WatchSubDirs)
                  }
                }
            GuiControl,, StartStop, Stop   
            SetTimer, WatchFolder, 20
}  Else      {
            Loop %DirIdx%
            {
               Dir%A_Index%         =
               Dir%A_Index%Path     =
               Dir%A_Index%Subdirs  =
               Dir%A_Index%FNI      =
               Dir%A_Index%Overlapped=
               DllCall( "CloseHandle", UInt,Dir%A_Index% )
               DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) ) 
            }
            DirIdx= 0
            SetTimer, WatchFolder, Off
            GuiControl,, StartStop, Start
  }

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

BeginWatchingDirectory(WatchFolder, WatchSubDirs=true)
{
    local hDir, hEvent
   
    Loop %DirIdx%
   {
      If InStr(WatchFolder, Dir%A_Index%Path)
      {
         If (WatchSubDirs and Dir%A_Index%Subdirs)
            Return
         else if (WatchSubDirs and !Dir%A_Index%Subdirs)
         {
            DllCall( "CloseHandle", UInt,Dir%A_Index% )
            DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) )
            #__RE_BEGINN_WATHING_DIR_ := DirIdx
            DirIdx := A_Index
         }
         Else
            Return
      }
      else if InStr(Dir%A_Index%Path, WatchFolder)
      {
         If (WatchSubDirs)
         {
            DllCall( "CloseHandle", UInt,Dir%A_Index% )
            DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) )
            #__RE_BEGINN_WATHING_DIR_ := DirIdx
            DirIdx := A_Index
         }
      }
   }
   If !#__RE_BEGINN_WATHING_DIR_
    DirIdx += 1
    ; CreateFile: http://msdn2.microsoft.com/en-us/library/aa914735.aspx
    hDir := DllCall( "CreateFile"
                 , Str  , WatchFolder
                 , UInt , ( FILE_LIST_DIRECTORY := 0x1 )
                 , UInt , ( FILE_SHARE_READ     := 0x1 )
                        | ( FILE_SHARE_WRITE    := 0x2 )
                        | ( FILE_SHARE_DELETE   := 0x4 )
                 , UInt , 0
                 , UInt , ( OPEN_EXISTING := 0x3 )
                 , UInt , ( FILE_FLAG_BACKUP_SEMANTICS := 0x2000000  )
                        | ( FILE_FLAG_OVERLAPPED       := 0x40000000 )
                 , UInt , 0 )
   
    Dir%DirIdx%         := hDir
    Dir%DirIdx%Path     := WatchFolder
    Dir%DirIdx%Subdirs  := WatchSubDirs
    VarSetCapacity( Dir%DirIdx%FNI, SizeOf_FNI )
    VarSetCapacity( Dir%DirIdx%Overlapped, 20, 0 )
    hEvent := DllCall( "CreateEvent", UInt,0, Int,true, Int,false, UInt,0 )
    NumPut( hEvent, Dir%DirIdx%Overlapped, 16 )
   
    ; Maintain array of event handles to wait on.
    if ( VarSetCapacity(DirEvents) < DirIdx*4 )
    {   ; Expand by 16 directories (64 bytes) at a time.
        VarSetCapacity(DirEvents, DirIdx*4 + 60)
        ; Copy all previous event handles.
        Loop %DirIdx%
        {
              NumPut( NumGet( Dir%A_Index%Overlapped, 16 ), DirEvents, A_Index*4-4 )
      }
    }
    NumPut( hEvent, DirEvents, DirIdx*4-4 )
   
    DllCall( "ReadDirectoryChangesW"  ; http://msdn2.microsoft.com/en-us/library/aa365465.aspx
                , UInt , hDir
                , UInt , &Dir%DirIdx%FNI
                , UInt , SizeOf_FNI
                , UInt , WatchSubDirs
                , UInt , ( FILE_NOTIFY_CHANGE_FILE_NAME   := 0x1   )
                       | ( FILE_NOTIFY_CHANGE_DIR_NAME    := 0x2   )
                       | ( FILE_NOTIFY_CHANGE_ATTRIBUTES  := 0x4   )
                       | ( FILE_NOTIFY_CHANGE_SIZE        := 0x8   )
                       | ( FILE_NOTIFY_CHANGE_LAST_WRITE  := 0x10  )
                       | ( FILE_NOTIFY_CHANGE_LAST_ACCESS := 0x20  )
                       | ( FILE_NOTIFY_CHANGE_CREATION    := 0x40  )
                       | ( FILE_NOTIFY_CHANGE_SECURITY    := 0x100 )
                , UInt , 0
                , UInt , &Dir%DirIdx%Overlapped
                , UInt , 0  )
    If #__RE_BEGINN_WATHING_DIR_
   {
      DirIdx := #__RE_BEGINN_WATHING_DIR_
      #__RE_BEGINN_WATHING_DIR_ =
   }
}

; Handles one directory at a time.
; Returns non-zero if a change was detected.
; Returns zero if it timed out or a window message was received.
ReadDirectoryChanges(Timeout=-1)
{
    local hDir, r
    ; Wait for any event object to be signaled or a window message to be received.
    r := DllCall("MsgWaitForMultipleObjectsEx", UInt, DirIdx, UInt, &DirEvents
                                            , UInt, Timeout, UInt, 0x4FF, UInt, 0x6)
    if (r >= 0 && r < DirIdx) ; WAIT_OBJECT_*
    {
        r += 1
        ; At least one event object was signaled. Decode the FNI for this event.
        ; If more than one event object was signaled, this func must be called again.
        WatchFolder := Dir%r%Path
        PointerFNI := &Dir%r%FNI
        nReadLen := 0
        DllCall( "GetOverlappedResult", UInt, hDir
                    , UInt, &Dir%r%Overlapped, UIntP, nReadLen, Int, true )
        gosub Decode_FILE_NOTIFY_INFORMATION

        ; Reset the event and call ReadDirectoryChangesW in async mode again.
        DllCall( "ResetEvent", UInt,NumGet( Dir%r%Overlapped, 16 ) )
        DllCall( "ReadDirectoryChangesW"
                , UInt , Dir%r%
                , UInt , &Dir%r%FNI
                , UInt , SizeOf_FNI
                , UInt , Dir%r%WatchSubDirs
                , UInt , ( FILE_NOTIFY_CHANGE_FILE_NAME   := 0x1   )
                       | ( FILE_NOTIFY_CHANGE_DIR_NAME    := 0x2   )
                       | ( FILE_NOTIFY_CHANGE_ATTRIBUTES  := 0x4   )
                       | ( FILE_NOTIFY_CHANGE_SIZE        := 0x8   )
                       | ( FILE_NOTIFY_CHANGE_LAST_WRITE  := 0x10  )
                       | ( FILE_NOTIFY_CHANGE_LAST_ACCESS := 0x20  )
                       | ( FILE_NOTIFY_CHANGE_CREATION    := 0x40  )
                       | ( FILE_NOTIFY_CHANGE_SECURITY    := 0x100 )
                , UInt , 0
                , UInt , &Dir%r%Overlapped
                , UInt , 0  )
        return r
    }
    return 0
}

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -


Decode_FILE_NOTIFY_INFORMATION:

;   PointerFNI := &FILE_NOTIFY_INFORMATION

  Loop {

    NextEntry   := NumGet( PointerFNI + 0  )
    Action      := NumGet( PointerFNI + 4  )
    FileNameLen := NumGet( PointerFNI + 8  )
    FileNamePtr :=       ( PointerFNI + 12 )


    If ( Action = 0x1 )                            ; FILE_ACTION_ADDED   
       Event := "New File"

    If ( Action = 0x2 )                            ; FILE_ACTION_REMOVED 
       Event := "Deleted"

    If ( Action = 0x3 )                            ; FILE_ACTION_MODIFIED 
       Event := "Modified"

    If ( Action = 0x4 )                            ; FILE_ACTION_RENAMED_OLD_NAME
       Event := "Renamed Fm"

    If ( Action = 0x5 )                            ; FILE_ACTION_RENAMED_NEW_NAME
       Event := "Renamed To"

    VarSetCapacity( FileNameANSI, FileNameLen )
    DllCall( "WideCharToMultiByte", UInt,0, UInt,0, UInt,FileNamePtr, UInt
           , FileNameLen,  Str,FileNameANSI, UInt,FileNameLen, UInt,0, UInt,0 )

    File := SubStr( FileNameANSI, 1, FileNameLen/2 )
    FullPath := WatchFolder . File
    FileGetAttrib, Attr, %FullPath%
    FormatTime, Time  , %A_Now%, HH:mm:ss

    If ( FileExist( FullPath ) = "" )
     {
       LV_Insert( 1, "", Time, Event, FullPath )
       Sb_SetText( "`t" LV_GetCount() )
     }
    Else
    Loop %FullPath%
     {
       FormatTime, TStamp, %A_LoopFileTimeModified%, yyyy-MM-dd  HH:mm:ss
       LV_Insert( 1, "", Time, Event, RegExReplace(FullPath, "\\\\", "\\"), A_LoopFileSizeKB, TStamp, A_LoopFileAttrib )
       Sb_SetText( "`t" LV_GetCount() )
     }

    If (!NextEntry or NextEntry = 4129024)
       Break
    Else
       PointerFNI := PointerFNI + NextEntry
  }

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

GuiClose:
ShutApp:

  Loop %DirIdx%
  {
     ToolTip % "Canceling watching " Dir%A_Index%Path
     Dir%A_Index%         =
     Dir%A_Index%Path     =
     Dir%A_Index%Subdirs  =
     Dir%A_Index%FNI      =
     Dir%A_Index%Overlapped=
     DllCall( "CloseHandle", UInt,Dir%A_Index% )
     DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) ) 
  }
  ExitApp

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

ClearListView:

 LV_Delete() , Sb_SetText("")

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Last edited by HotKeyIt on June 11th, 2009, 1:26 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 2nd, 2008, 5:58 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Did anyone give it a try? :?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 3rd, 2008, 9:34 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
I have added the edit field to FileSelectFolder, now you can even watch a network folder :D
- Fixed to display folder changes information.

Code:
#Persistent
SetBatchLines, -1
Process, Priority,, High
OnExit, ShutApp
Menu, Tray, Icon, Shell32.dll, 4
Menu, Tray, Tip , FolderSpy

WatchFolder  := A_Temp . "orary Internet Files"
WatchSubDirs := True

Loop %WatchFolder%, 1
      WatchFolder := A_LoopFileLongPath
DllCall( "shlwapi\PathAddBackslashA", UInt,&Watchfolder )

CBA_ReadDir := RegisterCallback("ReadDirectoryChanges")

; FILE_NOTIFY_INFORMATION : http://msdn2.microsoft.com/en-us/library/aa364391.aspx

SizeOf_FNI := ( 64KB := 1024 * 64 )
; VarSetCapacity( FILE_NOTIFY_INFORMATION, SizeOf_FNI, 0 )
; PointerFNI := &FILE_NOTIFY_INFORMATION

Gui, Margin, 5, 5
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder1, %WatchFolder%
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton1, ...
Gui, Add, Text     , x+40                                      , S
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder2,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton2, ...
Gui, Add, Text     , x+40                                      , U
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder3,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton3, ...
Gui, Add, Text     , x+40                                      , B
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder4,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton4, ...
Gui, Add, CheckBox , x+22      h18 vWatchSubDirs Checked 0x20,
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder5,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton5, ...
Gui, Add, Text     , x+40                                      , F
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder6,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton6, ...
Gui, Add, Text     , x+40                                      , O
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder7,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton7, ...
Gui, Add, Text     , x+40                                      , L
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder8,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton8, ...
Gui, Add, Text     , x+40                                      , D
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder9,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton9, ...
Gui, Add, Text     , x+40                                      , E
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder10,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton10, ...
Gui, Add, Text     , x+40                                      , R
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder11,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton11, ...
Gui, Add, Text     , x+40                                      , S
Gui, Add, Edit     , x5   w574 h18 +ReadOnly vWatchFolder12,
Gui, Add, Button   , x+5  w25  h18 gSelectFolder vBrowseButton12, ...
Gui, Add, Button   , x+5       h18 gDeleteSelection vDeleteSelection, DELETE ALL

Gui, Add, ListView , x5   w700 h380 +Grid vSpyLV
                   , Time|Event|File/Folder Name|Size-KB|TimeStamp [Mod]|Attrib
Gui, Add, Button   , x550  w64  h22 +Default vClear gClearListView, Clear
Gui, Add, Button   , x+10  w64  h22 +Default vStartStop gStartStop, Start

LV_ModifyCol( 1, "54" )
LV_ModifyCol( 2, "75  Center " )
LV_ModifyCol( 3, "327        " )
LV_ModifyCol( 4, "55  Integer" )
LV_ModifyCol( 5, "120        " )
LV_ModifyCol( 6, "46         " )

Gui, Add, StatusBar
SB_SetParts( 100, 500 )
GuiControl, Focus, StartStop
Gui, Show, , FolderSpy v0.97X

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
Return ;                                                  [| End of Auto-execute section |]
;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -


WatchFolder:

  ReadDirectoryChanges()

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
DeleteSelection:
If Watch
 Gosub, StartStop
Loop 12
 GuiControl,,WatchFolder%A_Index%
Return

SelectFolder:
    FileSelectFolder, SelFolder, *%WatchFolder%, 2, Select Watch Folder
   If ( SelFolder = "" )
   {
      GuiControl,,% "WatchFolder" . SubStr(A_GuiControl, 13)
      Return
    }
   If !(StrLen(SelFolder) = 3 and SubStr(SelFolder, 0) = "\")
   {
      Loop %SelFolder%, 1
      WatchFolder := A_LoopFileLongPath
      DllCall( "shlwapi\PathAddBackslashA", UInt,&Watchfolder )
   }
   else
      WatchFolder := SelFolder
   GuiControl,,% "WatchFolder" . SubStr(A_GuiControl, 13), %WatchFolder%
   GuiControl, Focus, StartStop
    SelFolder =
   If ( Watch )
    BeginWatchingDirectory(WatchFolder, WatchSubDirs)
Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

StartStop:

Watch := !Watch
  If ( Watch ) {
                DirIdx= 0
                Loop 12
                {
                  GuiControlGet, WatchFolder, , WatchFolder%A_Index%
                  If (WatchFolder != "")
                  {
                    BeginWatchingDirectory(WatchFolder, WatchSubDirs)
                  }
                }
            GuiControl,, StartStop, Stop   
            SetTimer, WatchFolder, 20
}  Else      {
            Loop %DirIdx%
            {
               Dir%A_Index%         =
               Dir%A_Index%Path     =
               Dir%A_Index%Subdirs  =
               Dir%A_Index%FNI      =
               Dir%A_Index%Overlapped=
               DllCall( "CloseHandle", UInt,Dir%A_Index% )
               DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) ) 
            }
            DirIdx= 0
            SetTimer, WatchFolder, Off
            GuiControl,, StartStop, Start
  }

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

BeginWatchingDirectory(WatchFolder, WatchSubDirs=true)
{
    local hDir, hEvent
   
    Loop %DirIdx%
   {
      If InStr(WatchFolder, Dir%A_Index%Path)
      {
         If (WatchSubDirs and Dir%A_Index%Subdirs)
            Return
         else if (WatchSubDirs and !Dir%A_Index%Subdirs)
         {
            DllCall( "CloseHandle", UInt,Dir%A_Index% )
            DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) )
            #__RE_BEGINN_WATHING_DIR_ := DirIdx
            DirIdx := A_Index
         }
         Else
            Return
      }
      else if InStr(Dir%A_Index%Path, WatchFolder)
      {
         If (WatchSubDirs)
         {
            DllCall( "CloseHandle", UInt,Dir%A_Index% )
            DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) )
            #__RE_BEGINN_WATHING_DIR_ := DirIdx
            DirIdx := A_Index
         }
      }
   }
   If !#__RE_BEGINN_WATHING_DIR_
    DirIdx += 1
    ; CreateFile: http://msdn2.microsoft.com/en-us/library/aa914735.aspx
    hDir := DllCall( "CreateFile"
                 , Str  , WatchFolder
                 , UInt , ( FILE_LIST_DIRECTORY := 0x1 )
                 , UInt , ( FILE_SHARE_READ     := 0x1 )
                        | ( FILE_SHARE_WRITE    := 0x2 )
                        | ( FILE_SHARE_DELETE   := 0x4 )
                 , UInt , 0
                 , UInt , ( OPEN_EXISTING := 0x3 )
                 , UInt , ( FILE_FLAG_BACKUP_SEMANTICS := 0x2000000  )
                        | ( FILE_FLAG_OVERLAPPED       := 0x40000000 )
                 , UInt , 0 )
   
    Dir%DirIdx%         := hDir
    Dir%DirIdx%Path     := WatchFolder
    Dir%DirIdx%Subdirs  := WatchSubDirs
    VarSetCapacity( Dir%DirIdx%FNI, SizeOf_FNI )
    VarSetCapacity( Dir%DirIdx%Overlapped, 20, 0 )
    hEvent := DllCall( "CreateEvent", UInt,0, Int,true, Int,false, UInt,0 )
    NumPut( hEvent, Dir%DirIdx%Overlapped, 16 )
   
    ; Maintain array of event handles to wait on.
    if ( VarSetCapacity(DirEvents) < DirIdx*4 )
    {   ; Expand by 16 directories (64 bytes) at a time.
        VarSetCapacity(DirEvents, DirIdx*4 + 60)
        ; Copy all previous event handles.
        Loop %DirIdx%
        {
              NumPut( NumGet( Dir%A_Index%Overlapped, 16 ), DirEvents, A_Index*4-4 )
      }
    }
    NumPut( hEvent, DirEvents, DirIdx*4-4 )
   
    DllCall( "ReadDirectoryChangesW"  ; http://msdn2.microsoft.com/en-us/library/aa365465.aspx
                , UInt , hDir
                , UInt , &Dir%DirIdx%FNI
                , UInt , SizeOf_FNI
                , UInt , WatchSubDirs
                , UInt , ( FILE_NOTIFY_CHANGE_FILE_NAME   := 0x1   )
                       | ( FILE_NOTIFY_CHANGE_DIR_NAME    := 0x2   )
                       | ( FILE_NOTIFY_CHANGE_ATTRIBUTES  := 0x4   )
                       | ( FILE_NOTIFY_CHANGE_SIZE        := 0x8   )
                       | ( FILE_NOTIFY_CHANGE_LAST_WRITE  := 0x10  )
                       | ( FILE_NOTIFY_CHANGE_LAST_ACCESS := 0x20  )
                       | ( FILE_NOTIFY_CHANGE_CREATION    := 0x40  )
                       | ( FILE_NOTIFY_CHANGE_SECURITY    := 0x100 )
                , UInt , 0
                , UInt , &Dir%DirIdx%Overlapped
                , UInt , 0  )
    If #__RE_BEGINN_WATHING_DIR_
   {
      DirIdx := #__RE_BEGINN_WATHING_DIR_
      #__RE_BEGINN_WATHING_DIR_ =
   }
}

; Handles one directory at a time.
; Returns non-zero if a change was detected.
; Returns zero if it timed out or a window message was received.
ReadDirectoryChanges(Timeout=-1)
{
    local hDir, r
    ; Wait for any event object to be signaled or a window message to be received.
    r := DllCall("MsgWaitForMultipleObjectsEx", UInt, DirIdx, UInt, &DirEvents
                                            , UInt, Timeout, UInt, 0x4FF, UInt, 0x6)
    if (r >= 0 && r < DirIdx) ; WAIT_OBJECT_*
    {
        r += 1
        ; At least one event object was signaled. Decode the FNI for this event.
        ; If more than one event object was signaled, this func must be called again.
        WatchFolder := Dir%r%Path
        PointerFNI := &Dir%r%FNI
        nReadLen := 0
        DllCall( "GetOverlappedResult", UInt, hDir
                    , UInt, &Dir%r%Overlapped, UIntP, nReadLen, Int, true )
        gosub Decode_FILE_NOTIFY_INFORMATION

        ; Reset the event and call ReadDirectoryChangesW in async mode again.
        DllCall( "ResetEvent", UInt,NumGet( Dir%r%Overlapped, 16 ) )
        DllCall( "ReadDirectoryChangesW"
                , UInt , Dir%r%
                , UInt , &Dir%r%FNI
                , UInt , SizeOf_FNI
                , UInt , Dir%r%WatchSubDirs
                , UInt , ( FILE_NOTIFY_CHANGE_FILE_NAME   := 0x1   )
                       | ( FILE_NOTIFY_CHANGE_DIR_NAME    := 0x2   )
                       | ( FILE_NOTIFY_CHANGE_ATTRIBUTES  := 0x4   )
                       | ( FILE_NOTIFY_CHANGE_SIZE        := 0x8   )
                       | ( FILE_NOTIFY_CHANGE_LAST_WRITE  := 0x10  )
                       | ( FILE_NOTIFY_CHANGE_LAST_ACCESS := 0x20  )
                       | ( FILE_NOTIFY_CHANGE_CREATION    := 0x40  )
                       | ( FILE_NOTIFY_CHANGE_SECURITY    := 0x100 )
                , UInt , 0
                , UInt , &Dir%r%Overlapped
                , UInt , 0  )
        return r
    }
    return 0
}

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -


Decode_FILE_NOTIFY_INFORMATION:

;   PointerFNI := &FILE_NOTIFY_INFORMATION

  Loop {

    NextEntry   := NumGet( PointerFNI + 0  )
    Action      := NumGet( PointerFNI + 4  )
    FileNameLen := NumGet( PointerFNI + 8  )
    FileNamePtr :=       ( PointerFNI + 12 )


    If ( Action = 0x1 )                            ; FILE_ACTION_ADDED   
       Event := "New File"

    If ( Action = 0x2 )                            ; FILE_ACTION_REMOVED 
       Event := "Deleted"

    If ( Action = 0x3 )                            ; FILE_ACTION_MODIFIED 
       Event := "Modified"

    If ( Action = 0x4 )                            ; FILE_ACTION_RENAMED_OLD_NAME
       Event := "Renamed Fm"

    If ( Action = 0x5 )                            ; FILE_ACTION_RENAMED_NEW_NAME
       Event := "Renamed To"

    VarSetCapacity( FileNameANSI, FileNameLen )
    DllCall( "WideCharToMultiByte", UInt,0, UInt,0, UInt,FileNamePtr, UInt
           , FileNameLen,  Str,FileNameANSI, UInt,FileNameLen, UInt,0, UInt,0 )

    File := SubStr( FileNameANSI, 1, FileNameLen/2 )
    FullPath := WatchFolder . File
    FileGetAttrib, Attr, %FullPath%
    FormatTime, Time  , %A_Now%, HH:mm:ss

    If ( FileExist( FullPath ) = "" )
     {
       LV_Insert( 1, "", Time, Event, FullPath )
       Sb_SetText( "`t" LV_GetCount() )
     }
    Else if ( FileExist( FullPath ) = "D" )
    Loop, %FullPath%, 2
     {
       FormatTime, TStamp, %A_LoopFileTimeModified%, yyyy-MM-dd  HH:mm:ss
       LV_Insert( 1, "", Time, Event, RegExReplace(FullPath, "\\\\", "\\"), A_LoopFileSizeKB, TStamp, A_LoopFileAttrib )
       Sb_SetText( "`t" LV_GetCount() )
     }
    Else
    Loop %FullPath%
     {
       FormatTime, TStamp, %A_LoopFileTimeModified%, yyyy-MM-dd  HH:mm:ss
       LV_Insert( 1, "", Time, Event, RegExReplace(FullPath, "\\\\", "\\"), A_LoopFileSizeKB, TStamp, A_LoopFileAttrib )
       Sb_SetText( "`t" LV_GetCount() )
     }

    If (!NextEntry or NextEntry = 4129024)
       Break
    Else
       PointerFNI := PointerFNI + NextEntry
  }

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

GuiClose:
ShutApp:

  Loop %DirIdx%
  {
     ToolTip % "Canceling watching " Dir%A_Index%Path
     Dir%A_Index%         =
     Dir%A_Index%Path     =
     Dir%A_Index%Subdirs  =
     Dir%A_Index%FNI      =
     Dir%A_Index%Overlapped=
     DllCall( "CloseHandle", UInt,Dir%A_Index% )
     DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) ) 
  }
  ExitApp

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

ClearListView:

 LV_Delete() , Sb_SetText("")

Return

;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Last edited by HotKeyIt on June 11th, 2009, 1:25 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 11th, 2009, 12:00 am 
Offline

Joined: August 21st, 2006, 7:07 pm
Posts: 2925
Location: The Shell
tic wrote:
Quote:
Let me know if you are interested and I will post an example for Asynchronous mode.


I am extremely interested!

Quote:
set up multiple callback functions, each using a DIFFERENT refrence for the directory to watch, but using all else the same.


I went and simplified skans original script to just show the changes as tooltips to make it easier for me to understand his code. would you be able to show me how you created N threads.

Code:
#Persistent
SetBatchLines, -1
Process, Priority,, High
OnExit, ShutApp

WatchFolder  := "C:"
WatchSubDirs := "1"

EventString := "New File,Deleted,Modified,Renamed From,Renamed To"
StringSplit, EventArray, EventString, `,

DllCall("shlwapi\PathAddBackslashA", UInt, &Watchfolder)

CBA_ReadDir := RegisterCallback("ReadDirectoryChanges")

SizeOf_FNI := ( 64KB := 1024 * 64 )
VarSetCapacity( FILE_NOTIFY_INFORMATION, SizeOf_FNI, 0 )
PointerFNI := &FILE_NOTIFY_INFORMATION

hDir := DllCall( "CreateFile", Str  , WatchFolder, UInt, "1", UInt , "7", UInt, 0, UInt, "3", UInt, "1107296256", UInt , 0 )

Loop
{
   nReadLen  := 0
   hThreadId := 0

   hThread   := DllCall( "CreateThread", UInt, 0, UInt, 0, UInt, CBA_ReadDir, UInt, 0, UInt,0, UIntP,hThreadId )
                  
   Loop
   {
      If nReadLen
      {
         PointerFNI := &FILE_NOTIFY_INFORMATION

         Loop
         {
            NextEntry   := NumGet( PointerFNI + 0  )
            Action      := NumGet( PointerFNI + 4  )
            FileNameLen := NumGet( PointerFNI + 8  )
            FileNamePtr :=       ( PointerFNI + 12 )
   
            Event := EventArray%Action%      

            VarSetCapacity( FileNameANSI, FileNameLen )
            DllCall( "WideCharToMultiByte", UInt,0, UInt,0, UInt,FileNamePtr, UInt, FileNameLen,  Str, FileNameANSI, UInt,FileNameLen, UInt,0, UInt,0 )

            File := SubStr( FileNameANSI, 1, FileNameLen/2 )
            FullPath := WatchFolder . File
            FileGetAttrib, Attr, %FullPath%
            FormatTime, Time  , %A_Now%, HH:mm:ss

            If !FileExist(FullPath)
            Tooltip, %Time%`n%Event%`n%File%
            Else
            {
               Loop %FullPath%
               {
                  FormatTime, TStamp, %A_LoopFileTimeModified%, yyyy-MM-dd  HH:mm:ss
                  Tooltip, %Time%`n%Event%`n%File%`n%A_LoopFileSizeKB%`n%TStamp%`n%A_LoopFileAttrib%
               }
            }   

            If !NextEntry
            Break
            Else
            PointerFNI += NextEntry
         }
         Break
      }           
   
      Sleep 100
   }

   DllCall( "TerminateThread", UInt,hThread, UInt,0 )
   DllCall( "CloseHandle", UInt,hThread )
}
Return

ReadDirectoryChanges()
{
   Global hDir,PointerFNI, Sizeof_FNI, WatchSubdirs, nReadlen
   Return DllCall( "ReadDirectoryChangesW", UInt, hDir, UInt, PointerFNI, UInt, SizeOf_FNI, UInt, WatchSubDirs, UInt, "375", UIntP, nReadLen, UInt, 0, UInt, 0 )
}

GuiClose:
ShutApp:
DllCall( "CloseHandle", UInt,hDir )
DllCall( "TerminateThread", UInt,hThread, UInt,0 )
DllCall( "CloseHandle", UInt,hThread )
ExitApp
Return


Trying to limit the file type to .wav and .mid. Any ideas of how I can do this??

_________________
Imageparadigm.shift:=(•_•)┌П┐RTFM||^.*∞


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 11th, 2009, 12:16 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Code:
...
SplitPath,FullPath,,,Ext
If !(Ext = "wav" or Ext = "mid")
 Sleep,-1
else
if !FileExist(FullPath)
Tooltip, %Time%`n%Event%`n%File%
Else
{
        Loop %FullPath%
       {
...

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 97 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Google Feedfetcher, maraskan_user and 17 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group