KeepTrackOnDirs - Verzeichnisüberwachung
Verfasst: 09.05.2008 14:20
Hi folks, da ich sehr of dateien aus diversen anwendungen heraus speichere und dann immer suchen muss (wegen vergesslichkeit) wo die denn nun liegen habe ich mal schnell ein tool programmiert, das ein ausgwähltes verzeichnis inkl. aller unterverzeichnisse überwacht und in einer liste anzeigt.
die erkannten dateien können per dragn drop direkt weiterverarbeitet werden.
viel spaß damit - und bitte vorschläge wenn man das besser machen kann!
die erkannten dateien können per dragn drop direkt weiterverarbeitet werden.
viel spaß damit - und bitte vorschläge wenn man das besser machen kann!
Code: Alles auswählen
; Watch a folder and all subfolder for changes
; dige 5/2008
; Compile with ThreadSafe enabled!!
; #FILE_NOTIFY_CHANGE_FILE_NAME
; #FILE_NOTIFY_CHANGE_DIR_NAME
; #FILE_NOTIFY_CHANGE_ATTRIBUTES
; #FILE_NOTIFY_CHANGE_SIZE
; #FILE_NOTIFY_CHANGE_LAST_WRITE
; #FILE_NOTIFY_CHANGE_SECURITY
Structure WatchFolder
Dir.s
WaitMillisecs.l
hChngObject.l
ThreadID.l
Flag.b
EndStructure
Structure FileList
FileName.s
FileSize.l
Date_Created.l
Date_Accessed.l
Date_Modified.l
Flag.b
EndStructure
Global NewList WF.WatchFolder()
Procedure DragNDropFile()
Protected File.s, Result.s
For i = 0 To CountGadgetItems(1)-1
If GetGadgetItemState(1, i) & #PB_ListIcon_Selected
File = GetGadgetItemText(1, i)
File = Trim(StringField( File, 2, ">" ))
If File : Result + File + Chr(10) : EndIf
EndIf
Next i
If Result : DragFiles(Result) : EndIf
EndProcedure
Procedure DoWatchFolder(*WF.WatchFolder)
Protected NewList FL.FileList(), DirID.l, Found.b, File.s, Count.l
Macro GetFileStuff
FL()\FileSize = FileSize (FL()\FileName)
FL()\Date_Created = GetFileDate( FL()\FileName, #PB_Date_Created )
FL()\Date_Accessed = GetFileDate( FL()\FileName, #PB_Date_Accessed )
FL()\Date_Modified = GetFileDate( FL()\FileName, #PB_Date_Modified )
EndMacro
With *WF
DirID = ExamineDirectory(#PB_Any, \Dir, "*.*")
; Add files
If DirID
While NextDirectoryEntry(DirID)
If DirectoryEntryType(DirID) = #PB_DirectoryEntry_File
If AddElement( FL() )
FL()\FileName = \Dir + "\" + DirectoryEntryName(DirID)
GetFileStuff
Else
ProcedureReturn
EndIf
EndIf
Wend
FinishDirectory(DirID)
EndIf
While \Flag = 0
\hChngObject=FindFirstChangeNotification_(\Dir, #Null, #FILE_NOTIFY_CHANGE_FILE_NAME|#FILE_NOTIFY_CHANGE_SIZE|#FILE_NOTIFY_CHANGE_LAST_WRITE)
If WaitForSingleObject_(\hChngObject, \WaitMillisecs) = 0
Count = 0
Repeat
DirID = ExamineDirectory(#PB_Any, \Dir, "*.*")
; check files
If DirID
ForEach FL()
FL()\Flag = 0
Next
While NextDirectoryEntry(DirID)
If DirectoryEntryType(DirID) = #PB_DirectoryEntry_File
Found = #False
ForEach FL()
If FL()\FileName = \Dir + "\" + DirectoryEntryName(DirID)
Found = 1
If FL()\FileSize <> FileSize (FL()\FileName) : Found = 2 : EndIf
If FL()\Date_Created <> GetFileDate( FL()\FileName, #PB_Date_Created ) : Found = 3 : EndIf
If FL()\Date_Accessed <> GetFileDate( FL()\FileName, #PB_Date_Accessed ) : Found = 4 : EndIf
If FL()\Date_Modified <> GetFileDate( FL()\FileName, #PB_Date_Modified ) : Found = 5 : EndIf
File = FL()\FileName
GetFileStuff
FL()\Flag = Found
Break
EndIf
Next
File = ""
If Not Found
If AddElement( FL() )
FL()\FileName = \Dir + "\" + DirectoryEntryName(DirID)
FL()\FileSize = FileSize (FL()\FileName)
GetFileStuff
File = FL()\FileName
FL()\Flag = 6
Found = 6 ; New File
EndIf
EndIf
EndIf
If File
Select Found
Case 2 : File = "NewFileSize > " + File
Case 3,4,5 : File = "NewDate > " + File
Case 6 : File = "NewFile > " + File
EndSelect
If Found <> 1 : Count + 1 : AddGadgetItem( 1, -1, "[" + Str(\ThreadID) + "] " + File ) : EndIf
File = ""
EndIf
Wend
FinishDirectory(DirID)
ForEach FL()
If FL()\Flag = 0
AddGadgetItem( 1, -1, "Deleted: " + FL()\FileName )
DeleteElement( FL() )
Count + 1
EndIf
Next
Else
Break 2
EndIf
Until Count = 0
EndIf
FindNextChangeNotification_(\hChngObject)
Wend
If \hChngObject
FindCloseChangeNotification_(\hChngObject)
EndIf
ClearList( FL () )
\ThreadID = 0
EndWith
EndProcedure
Procedure InitWatchFolder ( Dir.s )
If Right(Dir, 1) = "\" : Dir = Left(Dir, Len(Dir) - 1) : EndIf
DirID = ExamineDirectory(#PB_Any, Dir, "*.*")
If DirID
AddElement( WF() )
With WF()
\Dir = Dir
\WaitMillisecs = 2000; wait 1sec. to decrease cpu load
\ThreadID = CreateThread(@DoWatchFolder(), @WF())
ThreadPriority( \ThreadID, 1 ) ; decreas cpu load
EndWith
AddGadgetItem(1, -1, "Add: " + Dir )
While NextDirectoryEntry(DirID)
If DirectoryEntryType(DirID) = #PB_DirectoryEntry_Directory
If DirectoryEntryName(DirID) <> "." And DirectoryEntryName(DirID) <> ".."
InitWatchFolder( Dir + "\" + DirectoryEntryName(DirID) )
EndIf
EndIf
Wend
FinishDirectory(DirID)
EndIf
EndProcedure
Procedure.b QuitWatchFolder()
Protected Quit.b
ForEach WF()
If WF()\ThreadID And IsThread( WF()\ThreadID )
WF()\Flag = 1
EndIf
Next
TimeOut = ElapsedMilliseconds() + 50000
Repeat
Delay(200)
Count = 0
ForEach WF()
If WF()\ThreadID
Count + 1
EndIf
Next
Until Count = 0 Or TimeOut < ElapsedMilliseconds()
If Count = 0 : Quit = 1 : Else : Quit = 2 : EndIf
AddGadgetItem(1, -1, "QuitCode: " + Str(Quit))
ProcedureReturn Quit
EndProcedure
;{ MainLoop
If OpenWindow(0, 100, 200, 350, 400, "KeepTrackOnDirs by DiGe", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
If CreateGadgetList(WindowID(0))
ListIconGadget( 1, 0, 0, 350, 380, "", 345, #PB_ListIcon_MultiSelect|#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect )
ButtonGadget( 2, 0, 380, 100, 20, "Clear List" )
ButtonGadget( 3, 100, 380, 100, 20, "Quit Watch" )
EndIf
#INIFILE = "WatchFolder.ini"
Dir.s = ""
FileID = ReadFile( #PB_Any, #INIFILE )
If FileID
While Not Eof(FileID)
Dir = ReadString( FileID )
If Dir
InitWatchFolder( Dir )
EndIf
Wend
CloseFile(FileID)
Else
Dir = PathRequester( "WatchFolder", "" )
If Dir : InitWatchFolder( Dir ) : EndIf
EndIf
AddGadgetItem( 1, -1, "Watching " + Str(CountList(WF())) + " Folder(s)")
Repeat
EventID.l = WaitWindowEvent()
If EventID = #PB_Event_CloseWindow
Quit = QuitWatchFolder()
ElseIf EventID = #PB_Event_Gadget
Select EventGadget()
Case 1 : If EventType() = #PB_EventType_DragStart : DragNDropFile () : EndIf
Case 2 : ClearGadgetItemList(1)
Case 3 : Quit = QuitWatchFolder()
EndSelect
EndIf
Until Quit
While WindowEvent() : Wend
Delay(1000)
EndIf
;}
End