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 

Folder Spy to Copy Files

 
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
cjsmile999



Joined: 29 Jun 2009
Posts: 35

PostPosted: Wed Dec 23, 2009 4:45 pm    Post subject: Folder Spy to Copy Files Reply with quote

Hello Everyone,

I'm still trying to learn this and I'm at a lost. I found this really cool script on here called folder spy. I would really like to copy the new files to a new directory. Would someone be kind enough to assist, I'm really lost! Here is the folder spy script.

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

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


Thank you everyone for your time and assistance!
Back to top
View user's profile Send private message
greynite



Joined: 17 May 2008
Posts: 39
Location: Dallas, TX

PostPosted: Wed Dec 23, 2009 7:23 pm    Post subject: Reply with quote

To have the script "do" something, edit the section in this area:

Code:
    If ( FileExist( FullPath ) = "" )
     {
       LV_Insert( 1, "", Time, Event, FullPath )
       Sb_SetText( "`t" LV_GetCount() )
     }

And instead of or in addition to the LV_Insert, have your own subroutine to copy the file.

FWIW I intend to write & post a full blown "folder sync", to do a few tricks:
  • Simple copy
  • Copy + version number (poor mans version control Very Happy )
  • Copy + compress ( ZIP or better yet 7-zip )
  • Copy + compress + encrypt (static symmetric key using 7-zip AES256 , with optional salted key)
The last one in particular to let me store moderately sensative files in DropBox, since just the encrypted version will end up in the MyDropBox folder (I sooo wish I could use aufs+encfs on Windows!!!!) [ Those wishing better security could easily patch in GPG ]

Don't hold your breath, with 5 kids these side projects can take me months!

Cheers,
Shawn
Back to top
View user's profile Send private message
HotKeyIt



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

PostPosted: Wed Dec 23, 2009 7:40 pm    Post subject: Reply with quote

Try this Smile
It is a little modified version of WatchDirectory().
Code:
WatchFolders = C:\Temp*|%A_MyDocuments%* ;* means to watch in subfolders as well
CopyTo = x:\Temp



Loop,Parse,WatchFolders,|
   WatchDirectory(A_LoopField,"A1 FReport T100") ; A1= report new created files only









#Persistent
OnExit, Close
Return

Report(from, to){
   global
   FileCopy,% to,% _:= (CopyTo . SubStr(to,InStr(to,"\",1,0)))
}

Close:
WatchDirectory()
ExitApp



;Function WatchDirectory()
;
;WatchDirectory reports before / after situation so you will need to specify 2 variables, see V option
;
;Parameters
;      Directory         - Specify a valid path to watch for changes in.
;                        - can be directory or drive (e.g. c:\ or c:\Temp)
;                        - can be network path e.g. \\192.168.2.101\Shared)
;                        - can include last backslash. e.g. C:\Temp\ (will be reported same form)
;
;      SubDirs      - Specify whether to search in subfolders
;
;      Options            - E      Extensions filter separated by.      e.g. Eahk.txt.doc.xls.mdb
;                                 To report only folders use E?    only files E*
;                        - A      Action to report, to report all leave empty else A1234
;                                 1 Created - 2 Deleted - 3 Modified - 45 Renamed
;                        - G      Goto Label. Specify label to jump to when changes are registered   e.g. GRegisterChanges
;                                 ErrorLevel will contain before and after path separated by | e.g. 1|C:\test.txt
;                        - F      Function to launch when changes are registered. e.g. FReportChanges
;                                 Syntax of your Function must be e.g.ReportChanges(PathBefore,PathAfter)
;                                    - when file created, first var is empty and second var contains the path
;                                    - when file deleted, vice versa.
;                                    - when file modified, first and second var contain same path
;                                    - when file renamed, first var contains path renamed from, second var renamed to
;                        - T      Timer to register changes in milliseconds. e.g. T100
;
;StopWatching            -   THIS SHOULD BE DONE BEFORE EXITING SCRIPT AT LEAST (OnExit)
;      Call WatchDirectory() without parameters to stop watching all directories

WatchDirectory(Directory="", Options="",SubDirs=""){
   static
   local hDir, hEvent, r, Action, FileNameLen, pFileName, Restart, CurrentFolder, PointerFNI, option
   static nReadLen := 0, _SizeOf_FNI_:=65536
   If (Directory=""){
      Gosub, StopWatchingDirectories
      SetTimer,TimerDirectoryChanges,Off
   } else if (Directory=Chr(2) or IsFunc(Directory) or IsLabel(Directory)){
      Gosub, ReportDirectoryChanges
   } else {
      Loop % (DirIdx) {
         If InStr(Directory, Dir%A_Index%Path){
            If (Dir%A_Index%Subdirs)
               Return
         } else if InStr(Dir%A_Index%Path, Directory) {
            If (SubDirs){
               DllCall( "CloseHandle", UInt,Dir%A_Index% )
               DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) )
               Restart := DirIdx, DirIdx := A_Index
            }
         }
      }
      If !Restart
         DirIdx += 1
      r:=DirIdx
      Dir%r%Subdirs  := (SubDirs="" ? (SubStr(Directory,0)="*" ? 1 : 0) : SubDirs)
      StringReplace,Dir%r%Path,Dir%r%Path,*,,A
      Loop % Directory,2
         Directory:=A_LoopFileLongPath
      hDir := DllCall( "CreateFile"
                , Str  , Directory
                , 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%r%         := hDir
      Dir%r%Path     :=  (SubStr(Directory,0)=":") ? (Directory . "\") : Directory
      If (options!="")
         Loop,Parse,options,%A_Space%
            If (option:= SubStr(A_LoopField,1,1))
               Dir%r%%option%:= SubStr(A_LoopField,2)
      VarSetCapacity( Dir%r%FNI, _SizeOf_FNI_ )
      VarSetCapacity( Dir%r%Overlapped, 20, 0 )
      DllCall( "CloseHandle", UInt,hEvent )
      hEvent := DllCall( "CreateEvent", UInt,0, Int,true, Int,false, UInt,0 )
      NumPut( hEvent, Dir%r%Overlapped, 16 )
      if ( VarSetCapacity(DirEvents) < DirIdx*4 and VarSetCapacity(DirEvents, DirIdx*4 + 60))
         Loop %DirIdx%
         {
            If (SubStr(Dir%A_Index%Path,1,1)!="-"){
               action++
               NumPut( NumGet( Dir%action%Overlapped, 16 ), DirEvents, action*4-4 )
            }
         }
      NumPut( hEvent, DirEvents, DirIdx*4-4)
      Gosub, ReadDirectoryChanges
      If Restart
         DirIdx = %Restart%
      If (Dir%r%T!="")
         SetTimer,TimerDirectoryChanges,% Dir%r%T
   }
   Return
   TimerDirectoryChanges:
      WatchDirectory(Chr(2))
   Return
   ReportDirectoryChanges:
      r := DllCall("MsgWaitForMultipleObjectsEx", UInt, DirIdx, UInt, &DirEvents, UInt, -1, UInt, 0x4FF, UInt, 0x6) ;Timeout=-1
      if !(r >= 0 && r < DirIdx)
         Return
      r += 1
      CurrentFolder := Dir%r%Path
      PointerFNI := &Dir%r%FNI
      DllCall( "GetOverlappedResult", UInt, hDir, UInt, &Dir%r%Overlapped, UIntP, nReadLen, Int, true )
      Loop {
         pNext      := NumGet( PointerFNI + 0  )
         If (pNext > 65536)
            break
         Action      := NumGet( PointerFNI + 4  )
         FileNameLen := NumGet( PointerFNI + 8  )
         pFileName :=       ( PointerFNI + 12 )
         If (Action < 0x6){
            VarSetCapacity( FileNameANSI, FileNameLen )
            DllCall( "WideCharToMultiByte",UInt,0,UInt,0,UInt,pFileName,UInt,FileNameLen,Str,FileNameANSI,UInt,FileNameLen,UInt,0,UInt,0)
            path:=CurrentFolder . (SubStr(CurrentFolder,0)="\" ? "" : "\") . SubStr( FileNameANSI, 1, FileNameLen/2 )
            SplitPath,path,,,EXT
            SplitPath,frompath,,,EXTFrom
            If ((InStr(FileExist(path) . FileExist(frompath),"D") and Dir%r%E!="" and !InStr(Dir%r%E,"?")) or (Dir%r%A!="" and !InStr(Dir%r%A, action))){
               If (!pNext)
                  Break
               Else
                  frompath:=path, PointerFNI := (PointerFNI + pNext)
               Continue
            }
            option:=Dir%r%E="" ? "." : Dir%r%E
            Loop,Parse,option,.
               If (Dir%r%E=""
                  || ((InStr(FileExist(path),"D")) and InStr(Dir%r%E,"?"))
                  || (Dir%r%E="*" and !InStr(FileExist(path),"D"))
                  || (A_LoopField<>"" && (A_LoopField=EXT || A_LoopField=ExtFrom))){
                  If action in 2,3
                     before:=path,after:=(action=3 ? path : "")
                  else if action in 1,5
                     before:=(action=5 ? frompath : ""),after:=path
                  If (Directory and IsFunc(Directory))
                     %Directory%(action,path)
                  else if (action!=4){
                     If IsFunc(Dir%r%F){
                        F:=Dir%r%F
                        %F%(before,after)
                     }
                  }
                  If IsLabel(Dir%r%G){
                        ErrorLevel:=action . "|" . path
                        Gosub % Dir%r%G
                     }
                  break
               }
         }
         If (!pNext)
            Break
         Else
            frompath:=path, PointerFNI := (PointerFNI + pNext)
      }
      DllCall( "ResetEvent", UInt,NumGet( Dir%r%Overlapped, 16 ) )
      Gosub, ReadDirectoryChanges
   Return
   StopWatchingDirectories:
      Loop % (DirIdx) {
         DllCall( "CloseHandle", UInt,Dir%A_Index% )
         DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) )
         DllCall( "CloseHandle", UInt, NumGet(Dir%A_Index%Overlapped,16) )
         VarSetCapacity(Dir%A_Index%Overlapped,0)
         Dir%A_Index%=
         Dir%A_Index%Path=
         Dir%A_Index%Subdirs=
         Dir%A_Index%FNI=
      }
      DirIdx=
      VarSetCapacity(DirEvents,0)
   Return
   ReadDirectoryChanges:
      DllCall( "ReadDirectoryChangesW"
         , UInt , Dir%r%
         , UInt , &Dir%r%FNI
         , UInt , _SizeOf_FNI_
         , UInt , Dir%r%SubDirs
         , 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_CREATION    := 0x40  )
               ;| ( FILE_NOTIFY_CHANGE_SECURITY    := 0x100 )
         , UInt , 0
         , UInt , &Dir%r%Overlapped
         , UInt , 0  )
   Return
}

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun Wink
Back to top
View user's profile Send private message
cjsmile999



Joined: 29 Jun 2009
Posts: 35

PostPosted: Wed Dec 23, 2009 11:16 pm    Post subject: Reply with quote

Thank you guys for you reply. This is what I have so far:

Code:

    If ( FileExist( FullPath ) = "" )
     {
       LV_Insert( 1, "", Time, Event, FullPath )
      filecopy, %FullPath%, C:\here,1
      ErrorCount += ErrorLevel
        if ErrorLevel <> 0
         fileappend, %FullPath%, errorlog.txt
      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 )
      filecopy, %FullPath%, C:\here,1
      ErrorCount += ErrorLevel
        if ErrorLevel <> 0
         fileappend, %FullPath%, errorlog.txt
       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 )
      filecopy, %FullPath%, C:\here,1
      ErrorCount += ErrorLevel
        if ErrorLevel <> 0
         fileappend, %FullPath%, errorlog.txt
       Sb_SetText( "`t" LV_GetCount() )
     }


Greynite, I took you suggestion but added the new lines to each of the LV_Instert. Doing that seemed to capture all new files and modifcations. I'm sure I just hacked up this code, but it's the best I could come up with.

HotKeyIt, I'v tried your suggestion a little bit, but when I tried to modify it so it would copy modifcations as well I couldn't get it working.

I'm a total noob at this! Thank you both for your help!
Back to top
View user's profile Send private message
HotKeyIt



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

PostPosted: Thu Dec 24, 2009 2:09 am    Post subject: Reply with quote

Code:
WatchDirectory(A_LoopField,"A12345 FReport T100")

Quote:
1 Created - 2 Deleted - 3 Modified - 45 Renamed

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun Wink
Back to top
View user's profile Send private message
gregdowning



Joined: 10 Dec 2009
Posts: 12

PostPosted: Wed Mar 03, 2010 10:17 pm    Post subject: Reply with quote

What a great script!

I am trying to adapt it to copy a file to a new directory as soon as it is overwritten. The program I am using unfortunately overwrites the images it creates rather than writing out new frames for animation. I am an AHK noob so please excuse the lack of elegance in my code.

I have added a few lines to to copy the files to a new directory (see 2 "greg edits" below).

Code:
;:   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
;greg edit, pre loop set num
num := 1000
;end greg edit

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
  }

;Greg's Edit
{
    num++
}

;copy file
FileCopy, C:\Program Files\WorldMachine22Beta1\Examples\Tutorials\tutorial1output.tif, C:\here\file%num%\

; End greg's edit
Return



The problem is that it is writing 2 or 3 copies of the file and sometimes is not waiting until the file is done being written. I am sure this is a feature not a bug but I've seen this mentioned this above but don't quite understand how to make sure it only makes one copy of the file. Can someone explain how I can do this?

-Greg
Back to top
View user's profile Send private message
HotKeyIt



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

PostPosted: Thu Mar 04, 2010 6:25 am    Post subject: Reply with quote

As far as I can see, you are copying the file on any change so when it is deleted or modified as well.
Code:
If ( Action = 0x1 )     {                       ; FILE_ACTION_ADDED   
       Event := "New File"
       FileCopy,...
}

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun Wink
Back to top
View user's profile Send private message
gregdowning



Joined: 10 Dec 2009
Posts: 12

PostPosted: Mon Mar 15, 2010 1:30 am    Post subject: Reply with quote

Thanks for the tip HotKeyIt, but it did not resolve the problem.

I did some more testing and I thought the problem I was having was due to the polling of the folder. I tried saving a file into the directory that I knew would take a long time to write (2+ gig photoshop file) and it made 68 copies of the file rather than just 2 or 3.

So I thought I would change the timing by adding a sleep function that was longer than the time that it took to write the file.
Code:
  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"

      ;Greg's Edit
      sleep 30000
      {
             num++
      }
      ;copy file
      FileCopy, C:\Program Files\WorldMachine22Beta1\Examples\Tutorials\tutorial1output.tif, C:\here\file%num%\
      ; End greg's edit

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

No dice Sad it still writes multiple files, it just waits longer to do it. Anyone have some insight to this problem?
Back to top
View user's profile Send private message
garry



Joined: 19 Apr 2005
Posts: 2212
Location: switzerland

PostPosted: Mon Mar 15, 2010 4:05 pm    Post subject: Reply with quote

hello Greg
didn't checked script
maybe can you use this (?)
http://www.autohotkey.com/forum/post-339792.html#339792
Back to top
View user's profile Send private message
gregdowning



Joined: 10 Dec 2009
Posts: 12

PostPosted: Mon Mar 15, 2010 5:59 pm    Post subject: Reply with quote

Thanks for your help Garry, but I don't understand how this would either copy a file once it is overwritten or prevent the script above from making multiple copies.
Back to top
View user's profile Send private message
garry



Joined: 19 Apr 2005
Posts: 2212
Location: switzerland

PostPosted: Mon Mar 15, 2010 6:22 pm    Post subject: Reply with quote

sorry Greg,
it doesn't overwrite, create new numbered copies ....
Back to top
View user's profile Send private message
gregdowning



Joined: 10 Dec 2009
Posts: 12

PostPosted: Fri Apr 09, 2010 10:55 pm    Post subject: Reply with quote

I never got this to work, although I think a general listening and copying function would be handy since I have needed something like this multiple times I found a workaround. If anyone else is searching for this function and dealing only with image formats Adobe Lightroom has this function under File --> AutoImport.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
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