AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Crazy Scripting : FolderSpy v0.96 [ Synchronous ]
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
IN2ITive



Joined: 15 Apr 2008
Posts: 44

PostPosted: Sun May 25, 2008 6:13 pm    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
joemoeschmoe



Joined: 25 Jun 2008
Posts: 25

PostPosted: Wed Jun 25, 2008 1:44 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Wed Jun 25, 2008 1:56 pm    Post subject: Reply with quote

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.

Smile
_________________
URLGet - Internet Explorer based Downloader
Back to top
View user's profile Send private message Send e-mail
joemoeschmoe



Joined: 25 Jun 2008
Posts: 25

PostPosted: Wed Jun 25, 2008 2:13 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Wed Jun 25, 2008 2:31 pm    Post subject: Reply with quote

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:

Smile
_________________
URLGet - Internet Explorer based Downloader
Back to top
View user's profile Send private message Send e-mail
caterva



Joined: 09 Apr 2008
Posts: 14

PostPosted: Sun Aug 31, 2008 9:45 pm    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Thu Oct 09, 2008 6:37 am    Post subject: Reply with quote

Many thanks for this script SKAN, it is really great Very Happy

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. Smile

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
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 7299
Location: Australia

PostPosted: Fri Nov 28, 2008 8:27 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message Visit poster's website
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Fri Nov 28, 2008 2:20 pm    Post subject: Reply with quote

Many thanks Lexikos, will try to get it working.
_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun Wink
Back to top
View user's profile Send private message
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Fri Nov 28, 2008 11:25 pm    Post subject: Reply with quote

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 Thu Jun 11, 2009 12:27 am; edited 1 time in total
Back to top
View user's profile Send private message
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Mon Dec 01, 2008 7:06 am    Post subject: Reply with quote

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 Thu Jun 11, 2009 12:26 am; edited 1 time in total
Back to top
View user's profile Send private message
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Tue Dec 02, 2008 4:58 pm    Post subject: Reply with quote

Did anyone give it a try? Confused
Back to top
View user's profile Send private message
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Wed Dec 03, 2008 8:34 pm    Post subject: Reply with quote

I have added the edit field to FileSelectFolder, now you can even watch a network folder Very Happy
- 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 Thu Jun 11, 2009 12:25 am; edited 1 time in total
Back to top
View user's profile Send private message
TLM



Joined: 21 Aug 2006
Posts: 2926
Location: The Shell

PostPosted: Wed Jun 10, 2009 11:00 pm    Post subject: Reply with quote

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??
_________________
paradigm.shift:=(•_•)┌П┐RTFM||^.*∞
Back to top
View user's profile Send private message
HotKeyIt



Joined: 18 Jun 2008
Posts: 4653
Location: AHK Forum

PostPosted: Wed Jun 10, 2009 11:16 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
Page 6 of 7

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group