Das ständige einlesen eines Verzeichnisses ist gar nicht notwendig, um Veränderungen mitzubekommen. Windows bietet dafür eine eventbasierte Möglichkeit. So wird das Verzeichnis nur bei Veränderungen neu eingelesen.
Hier mal ein (sehr ausführliches) Beispiel:
AutoIt
#include <APIShellExConstants.au3>
#include <Date.au3>
#include <FileConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <GuiListView.au3>
#include <GuiStatusBar.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WinAPIConv.au3>
#include <WinAPIFiles.au3>
#include <WinAPILocale.au3>
#include <WinAPIRes.au3>
#include <WinAPIShellEx.au3>
#include <WinAPIShPath.au3>
#include <WinAPISysWin.au3>
Global $g_sPath = @ScriptDir ; <- hier das zu ueberwachende Verzeichnis eintragen
If StringRight($g_sPath, 1) <> '\' Then $g_sPath &= '\'
Global $g_iID = 0, $g_bStart = False
Global $g_hBusyCur = _WinAPI_LoadCursorFromFile(@WindowsDir & '\Cursors\aero_busy_xl.ani') ; Busy-Animation-Cursor laden
OnAutoItExitRegister('_OnAutoItExit')
_WinAPI_FileIconInit()
Global $g_bLargeIcons = True ; ob grosse oder kleine Icons benutzt werden sollen
Global $g_hSystemImgList = _WinAPI_ShellGetImageList(Not $g_bLargeIcons) ; System-Imagelist holen
Global $g_hGui = GUICreate('Verzeichnisüberwachung "' & $g_sPath & '"', 800, 600)
Global $g_idFilelist = GUICtrlCreateListView('Name|Größe (Bytes)|Datum|Attr', 5, 5, 790, 565)
GUICtrlSetFont(-1, 9 + $g_bLargeIcons * 3, 400, 0, 'Arial')
GUICtrlSetBkColor(-1, 0xF8F8F8)
_GUICtrlListView_SetColumnWidth($g_idFilelist, 0, 360)
_GUICtrlListView_SetColumnWidth($g_idFilelist, 1, 150)
_GUICtrlListView_SetColumnWidth($g_idFilelist, 2, 170)
_GUICtrlListView_SetColumnWidth($g_idFilelist, 3, 70)
_GUICtrlListView_JustifyColumn($g_idFilelist, 1, 1)
_GUICtrlListView_SetImageList($g_idFilelist, $g_hSystemImgList, 1)
Global $g_hStatus = _GUICtrlStatusBar_Create($g_hGui)
Local $g_iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY')
GUIRegisterMsg($g_iMsg, '_WM_SHELLCHANGENOTIFY')
$g_iID = _WinAPI_ShellChangeNotifyRegister($g_hGui, $g_iMsg, $SHCNE_ALLEVENTS, _
BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $g_sPath, False)
GUISetState(@SW_SHOW, $g_hGui)
_GetFilesFolder($g_idFilelist, $g_sPath) ; Bei Programmstart die Verzeichnisse/Dateien einlesen
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func _OnAutoItExit()
If $g_iID Then _WinAPI_ShellChangeNotifyDeregister($g_iID)
If $g_hBusyCur Then _WinAPI_DestroyCursor($g_hBusyCur)
_GUIImageList_Destroy($g_hSystemImgList)
EndFunc ;==>_OnAutoItExit
Func _WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam, $lParam
If Not $g_bStart Then ; es koennen mehrere Events "gleichzeitig" erfolgen
$g_bStart = True ; um dabei ein mehrfaches Einlesen zu verhindern
AdlibRegister('_StartReading', 100) ; wird das Einlesen erst nach 100 ms aufgerufen
EndIf
EndFunc ;==>_WM_SHELLCHANGENOTIFY
Func _StartReading()
AdlibUnRegister('_StartReading')
_GetFilesFolder($g_idFilelist, $g_sPath)
$g_bStart = False
EndFunc ;==>_StartReading
Func _GetFilesFolder($idLV, $sPath)
Local $tNUMBERFMT, $hOldCur, $aFolder, $aFiles, $iIndex
$tNUMBERFMT = _WinAPI_CreateNumberFormatInfo(0, 1, 3, '', '.', 1)
_GUICtrlListView_BeginUpdate($idLV)
_GUICtrlListView_DeleteAllItems($idLV)
$hOldCur = _WinAPI_SetCursor($g_hBusyCur)
$aFolder = _WinAPI_EnumFiles($sPath, 2) ; Erst alle Verzeichnisse einlesen
If Not @error Then
Local $aNewItems[$aFolder[0][0]][5] ; 'Name|Groesse|Attr'
For $i = 1 To $aFolder[0][0]
$iIndex = _GUIImageList_GetFileIconIndex($sPath & $aFolder[$i][0], $g_bLargeIcons, True)
$aNewItems[$i - 1][0] = $iIndex
$aNewItems[$i - 1][1] = $aFolder[$i][0]
$aNewItems[$i - 1][2] = '<DIR>'
$aNewItems[$i - 1][3] = _DateTimeFormat(_GetDateTime($aFolder[$i][3]), 0)
$aNewItems[$i - 1][4] = _GetAttrChars($aFolder[$i][6])
Next
_GUICtrlListView_AddArrayEx($idLV, $aNewItems)
EndIf
$aFiles = _WinAPI_EnumFiles($sPath, 1) ; danach alle Dateien einlesen
If Not @error Then
Local $aNewItems[$aFiles[0][0]][5] ; 'Name|Groesse|Attr'
For $i = 1 To $aFiles[0][0]
$iIndex = _GUIImageList_GetFileIconIndex($sPath & $aFiles[$i][0], $g_bLargeIcons, False)
$aNewItems[$i - 1][0] = $iIndex
$aNewItems[$i - 1][1] = $aFiles[$i][0]
$aNewItems[$i - 1][2] = _WinAPI_GetNumberFormat(0, $aFiles[$i][4], $tNUMBERFMT)
$aNewItems[$i - 1][3] = _DateTimeFormat(_GetDateTime($aFiles[$i][3]), 0)
$aNewItems[$i - 1][4] = _GetAttrChars($aFiles[$i][6])
Next
_GUICtrlListView_AddArrayEx($idLV, $aNewItems)
EndIf
_WinAPI_SetCursor($hOldCur)
_GUICtrlListView_EndUpdate($idLV)
_GUICtrlStatusBar_SetText($g_hStatus, StringFormat('Letzte Änderung: %02i.%02i.%04i %02i:%02i:%02i\r\n', @MDAY, @MON, @YEAR, @HOUR, @MIN, @SEC))
EndFunc ;==>_GetFilesFolder
Func _GetAttrChars($iAttr)
Local Const $aFA[][2] = [[$FILE_ATTRIBUTE_READONLY, 'R'], [$FILE_ATTRIBUTE_ARCHIVE, 'A'], _
[$FILE_ATTRIBUTE_SYSTEM, 'S'], [$FILE_ATTRIBUTE_HIDDEN, 'H']]
Local $sAttr = ''
For $i = 0 To UBound($aFA) - 1
$sAttr &= BitAND($iAttr, $aFA[$i][0]) ? $aFA[$i][1] : '-'
Next
Return $sAttr
EndFunc ;==>_GetAttrChars
Func _GetDateTime($iDWord)
Local $tFILETIME = DllStructCreate($tagFILETIME), $tLOCAL
DllStructSetData($tFILETIME, 1, _WinAPI_LoDWord($iDWord))
DllStructSetData($tFILETIME, 2, _WinAPI_HiDWord($iDWord))
$tLOCAL = _Date_Time_FileTimeToLocalFileTime($tFILETIME)
Return _Date_Time_FileTimeToStr($tLOCAL, 1)
EndFunc ;==>_GetDateTime
Func _GUIImageList_GetFileIconIndex($sFilePath, $bLargeIcons = False, $bForceLoadFromDisk = False)
Local $tFileInfo = DllStructCreate($tagSHFILEINFO)
Local $iFlags = BitOR($SHGFI_SYSICONINDEX, _
$bLargeIcons ? $SHGFI_LARGEICON : $SHGFI_SMALLICON, _
$bForceLoadFromDisk ? 0 : $SHGFI_USEFILEATTRIBUTES)
Local $ret = _WinAPI_ShellGetFileInfo($sFilePath, $iFlags, $FILE_ATTRIBUTE_NORMAL, $tFileInfo)
If $ret Then Return DllStructGetData($tFileInfo, 'iIcon')
Return SetError(1, 0, -1)
EndFunc ;==>_GUIImageList_GetFileIconIndex
; Bei dieser Version von _GUICtrlListView_AddArray kann man auch den Image-Index angeben
Func _GUICtrlListView_AddArrayEx($hWnd, ByRef $aItems)
Local $fUnicode, $tItem, $pItem, $tBuffer, $pBuffer, $iLastItem
$fUnicode = _GUICtrlListView_GetUnicodeFormat($hWnd)
$tItem = DllStructCreate($tagLVITEM)
$pItem = DllStructGetPtr($tItem)
If $fUnicode Then
$tBuffer = DllStructCreate('wchar Text[4096]')
Else
$tBuffer = DllStructCreate('char Text[4096]')
EndIf
$pBuffer = DllStructGetPtr($tBuffer)
DllStructSetData($tItem, 'Mask', BitOR($LVIF_TEXT, $LVIF_IMAGE)) ; <- $LVIF_IMAGE hinzugefügt
DllStructSetData($tItem, 'Text', $pBuffer)
DllStructSetData($tItem, 'TextMax', 4096)
$iLastItem = _GUICtrlListView_GetItemCount($hWnd)
For $i = 0 To UBound($aItems) - 1
DllStructSetData($tItem, 'Item', $i + $iLastItem)
DllStructSetData($tItem, 'SubItem', 0)
DllStructSetData($tItem, 'Image', $aItems[$i][0]) ; <- Den Image-Index als Element 0 im Array
DllStructSetData($tBuffer, 'Text', $aItems[$i][1])
If $fUnicode Then
GUICtrlSendMsg($hWnd, $LVM_INSERTITEMW, 0, $pItem)
Else
GUICtrlSendMsg($hWnd, $LVM_INSERTITEMA, 0, $pItem)
EndIf
For $j = 2 To UBound($aItems, 2) - 1
DllStructSetData($tItem, 'SubItem', $j - 1)
DllStructSetData($tBuffer, 'Text', $aItems[$i][$j])
If $fUnicode Then
GUICtrlSendMsg($hWnd, $LVM_SETITEMW, 0, $pItem)
Else
GUICtrlSendMsg($hWnd, $LVM_SETITEMA, 0, $pItem)
EndIf
Next
Next
$tItem = 0
$tBuffer = 0
EndFunc ;==>_GUICtrlListView_AddArrayEx
Alles anzeigen