Regelmäßige Dateiabfrage und ggf. Array neu einlesen

  • Steh mal wieder vor einer Aufgabe bei der ich nicht weiß wie ich da rangehen soll und eure Hilfe benötige.

    Habe ein Programm, dass mit einem Array arbeitet, das bei Programmstart eingelesen wird. Nun wird die Datei aber laut Plan einmal am Tag erneuert und entweder soll das programm dieses erkennen oder einfach regelmäßig das array zu ner tageszeit neu einlesen.

    Edit: Wiedermal zu voreilich gehandelt. sollte mit _Gettime() irgendwie möglich sein.

    Die erste Variante mit dem erkennen von einer Änderung in der Datei scheint mir deutlich aufwendiger. Wenn jemand dazu aber ne Idee hat immer gerne her damit.

    Einmal editiert, zuletzt von miks.de (7. November 2012 um 12:18)

  • fileTime °°

    Spoiler anzeigen
    [autoit]


    Local $t = FileGetTime(@WindowsDir & "\notepad.exe", 1)

    [/autoit] [autoit][/autoit] [autoit]

    If Not @error Then
    Local $yyyymd = $t[0] & "/" & $t[1] & "/" & $t[2]
    MsgBox(0, "Creation date of notepad.exe", $yyyymd)
    EndIf

    [/autoit]
  • Es ist ziemlich ineffizient permanent AutoIt prüfen zu lassen ob sich eine Datei geändert hat.
    Windows schmeißt in einem solchen Falle eh eine Meldung so dass man AutoIt einfach auf diese warten lassen und ansonsten schlafen lassen kann.

    Das ist zwar etwas aufwändiger umzusetzen aber wenn es dann mal funktioniert ist diese Lösung deutlich eleganter.
    Hier mal ein kleines Beispiel:

    Auf Änderung in einer Datei warten
    [autoit]

    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $s_Path = FileGetLongName("D:\Test.txt") ; hier den zu prüfenden Pfad eintragen
    If Not FileExists($s_Path) Then Exit MsgBox(48, "Fehler", "Pfad " & $s_Path & " existiert nicht!")

    [/autoit] [autoit][/autoit] [autoit]

    Opt("TrayMenuMode", 1)
    Opt("TrayOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $SHCNE_RENAMEITEM = 0x0001 ; Änderung von Dateinamen
    Global Const $SHCNE_CREATE = 0x0002 ; Erstellung von Dateien
    Global Const $SHCNE_DELETE = 0x0004 ; Löschen von Dateien
    Global Const $SHCNE_MKDIR = 0x0008 ; Erstellung von Ordnern
    Global Const $SHCNE_RMDIR = 0x0010 ; Löschen von Ordnern
    Global Const $SHCNE_UPDATEDIR = 0x1000 ; Änderungen in einem Pfad
    Global Const $SHCNE_UPDATEITEM = 0x2000 ; Änderungen in einer Datei
    Global Const $SHCNE_UPDATEIMAGE = 0x8000
    Global Const $SHCNE_RENAMEFOLDER = 0x20000
    Global Const $SHCNE_ALLEVENTS = 0x7FFFFFFF ; weitere siehe http://msdn.microsoft.com/en-us/library/…8(v=vs.85).aspx

    [/autoit] [autoit][/autoit] [autoit]

    Global $h_Shell32DLL = DllOpen("shell32.dll")

    [/autoit] [autoit][/autoit] [autoit]

    ; Registriert ein FileSystemEvent mit einer AutoIt-Callback-Funktion
    Global $SHRegister = RegisterFSEvent($s_Path, $SHCNE_UPDATEITEM, "EvaluateEvents", False)

    [/autoit] [autoit][/autoit] [autoit]

    ; Erstelle ein Tray-Menü fürs Beenden
    OnAutoItExitRegister("Raus")
    TrayCreateItem("Beenden")
    TrayItemSetOnEvent(-1, "Beenden")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Endlosschleife damit AutoIt die meiste Zeit über pausiert ist (Beenden über das Tray-Icon möglich)
    Do
    Sleep(500)
    Until 0

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Funktion die aufgerufen wird wenn ein Event auftritt:
    Func EvaluateEvents(Const $hWndGUI, Const $MsgID, Const $wParam, Const $lParam)
    Local $h_pidl = DllStructCreate("PTR; PTR", $wParam)
    Local $a_Ret = DllCall($h_Shell32DLL, "BOOLEAN", "SHGetPathFromIDListW", "ptr", DllStructGetData($h_pidl, 1), "wstr", "")
    Local $s_Path = $a_Ret[2]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Switch $lParam ; Welche Art von Event ist aufgetreten?
    Case $SHCNE_UPDATEITEM ; Wenn ein Element nur vom Inhalt her geändert wurde
    MsgBox(0, "Änderung", "Änderung an folgender Datei festgestellt: " & $s_Path)
    EndSwitch
    ; EndIf
    EndFunc ;==>CheckOfNewFiles

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; registriert ein FileSystemEvent eines Pfades mit einer Funktion
    Func RegisterFSEvent(Const $s_Path, Const $d_Events, Const $s_CallBackFunc, Const $bRecursive = True)
    Local $h_MyWinMsg = _WinAPI_RegisterWindowMessage("irgendwas")
    Local $h_GUI = GUICreate("")
    GUIRegisterMsg($h_MyWinMsg, $s_CallBackFunc)

    [/autoit] [autoit][/autoit] [autoit]

    Local $h_PIDLIST = DllCall($h_Shell32DLL, "PTR", "ILCreateFromPathW", "WSTR", $s_Path)
    Local $strct_SHChangeNotifyEntry = DllStructCreate("PTR pidl; BOOLEAN fRecursive")
    DllStructSetData($strct_SHChangeNotifyEntry, 1, $h_PIDLIST[0])
    DllStructSetData($strct_SHChangeNotifyEntry, 2, $bRecursive)

    [/autoit] [autoit][/autoit] [autoit]

    Local $SHRegister = DllCall($h_Shell32DLL, "int", "SHChangeNotifyRegister", _
    "HWND", $h_GUI, _
    "INT", 0x0003, _
    "LONG", $d_Events, _
    "UINT", $h_MyWinMsg, _
    "INT", 1, _
    "ptr", DllStructGetPtr($strct_SHChangeNotifyEntry))
    DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $h_PIDLIST[0])
    Return $SHRegister
    EndFunc ;==>RegisterFSEvent

    [/autoit] [autoit][/autoit] [autoit]

    Func Beenden()
    Exit
    EndFunc ;==>Beenden

    [/autoit] [autoit][/autoit] [autoit]

    Func Raus()
    DllCall($h_Shell32DLL, "BOOLEAN", "SHChangeNotifyDeregister", "ULONG", $SHRegister[0])
    DllClose($h_Shell32DLL)
    EndFunc ;==>Raus

    [/autoit]


    Du musst erstmal eigentlich nur Zeile 3 an deinen Pfad anpassen.
    Was bei einem Änderungsevent mit der Datei passieren soll steht dann in Zeile 47.

  • hab es jetzt erstmal so gelöst, dass er zu einer bestimmten Zeit das Array neu einliest.. also in der hauptschleife.. werde es aber zu gegebener Zeit nochmal mit deiner Lösung anpassen.

    Spoiler anzeigen
    [autoit]


    While 1
    if _GetTime() = "13:00" Then
    _arrayeinlesen()
    EndIf
    Wend

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetTime()
    Return @Hour & ":" & @Min
    EndFunc

    [/autoit]
  • Es ist ziemlich ineffizient permanent AutoIt prüfen zu lassen ob sich eine Datei geändert hat.
    Windows schmeißt in einem solchen Falle eh eine Meldung so dass man AutoIt einfach auf diese warten lassen und ansonsten schlafen lassen kann.

    Das ist zwar etwas aufwändiger umzusetzen aber wenn es dann mal funktioniert ist diese Lösung deutlich eleganter.


    Nice, das landet mal in meiner Script Sammlung. ;)
    Kann ich sehr gut gebrauchen, hab etliche Scripte die Dateien oder Ordner periodisch auf Veränderung prüfen.

  • hmm wollte es jetzt mal umbauen auf die Lösung von AspirinJunkie, aber es funktioniert bei mir nicht.

    muss doch nur den Pfad der Datei umschreiben dann sollte doch zumindest ne Msgbox kommen wenn ich die Datei verändere oder nicht?