Skript als Service bricht nach etwa 16-18 Stunden unerklärlich ab

  • Hallo,

    ich habe ein AutoIt-Skript erstellt, mit dem ich Pdf-Dateien, die in einem Verzeichnis ausgegeben werden, mit dem externen Tool Pdfp an einen Drucker schicke. Der Name des Druckers ist dabei der Name des Unterverzeichnisses, in welchem die Pdf-Dateien erstellt werden. Der UNC-Pfad ergibt sich dabei aus der Variablen $printserver und dem Verzeichnisnamen. Das Script gibt in einer Text-Datei aus, wann es startet und wann es abbricht. Dabei wurde mir allerdings nichts fehlerhaftes mitgeteilt, nur dass das Script beendet wurde. Dies geschieht aber nach einiger Zeit automatisch, da ansonsten der Speicherverbrauch exponentiell anwächst und das Script deshalb neugestartet werden muss. Hier poste ich euch den Code in der Hoffnung, dass jemand, der Ahnung von AutoIt hat, den Fehler finden möge ;)

    Spoiler anzeigen
    [autoit]


    #Include <File.au3>

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

    $envPath = "c:\pdfs"
    $printserver = "\\nt-printserver"
    $pdfpExe = "pdfp.exe"
    $logFile = "pdfs.log"
    $spoolerFile = "pdf_spooler.exe"
    $restartZeit = 7200000 ; wartet x Stunden und startet dann das Skript erneut
    $warteZyklus = 500 ; zwischen den einzelnen Abtastzyklen existiert eine Pause von x Sekunden, um den physischen Speicher zu schonen

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

    WinSetState("System Properties","",@SW_HIDE)

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

    ; Die Anfangszeit des Skriptes wird in $startZeit für spätere Vergleiche festgehalten
    $startZeit = TimerInit()

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

    ; Umgebungsverzeichnis auf $envPath setzen
    FileChangeDir ($envPath)

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

    Opt("OnExitFunc", "endscript")

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

    Func endscript()
    ; Log-Datei zum Schreiben von Status öffnen
    $log = FileOpen("fehler.log", 1)
    FileWriteLine($log, @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @SEC & " Service beendet durch " & @EXITMETHOD & ". Fehler: " & @error)
    FileClose($log)
    EndFunc

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

    ; Wenn Logdatei noch nicht existiert, dann neu anlegen
    if Not FileExists($logFile) Then _FileCreate($logFile)

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

    ; Log-Datei zum Schreiben von Status öffnen
    $log = FileOpen($logFile, 1)

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

    ; Prüfen, ob ausreichend Speicherplatz (>=50 MBytes) auf der Festplatte vorhanden ist
    $freeSpace = DriveSpaceFree($envpath)
    If $freeSpace < 50 Then
    $errText = "Der freie Speicherplatz beträgt weniger als 50 MBytes. Programm wird beendet."
    ;MsgBox(0, "Error", $errText)
    FileWriteLine($log, $errText)
    FileClose($log)
    Exit
    EndIf

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

    FileWriteLine($log, @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @SEC & " Service gestartet.")
    FileClose($log)

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

    ; Die äußere Schleife wird durchlaufen, wenn keine Ordner in c:\pdfs vorhanden sind, Ordner vorhanden sind oder wenn Dateien in den Ordnern vorhanden sind.
    While 1

    ; Wenn das Script bereits länger als die in $restartZeit angegebene Zeit durchläuft, wird es neugestartet, um den Verbrauch an physischem Speicher, der mit der Zeit
    ; zunimmt, zu reduzieren
    $dif = TimerDiff($startZeit)
    if $dif > $restartZeit then
    $ret = Run(@ComSpec & ' /c start /MIN ' & 'pdf_spooler.exe', $envPath, @SW_HIDE, 2 + 4)
    Exit
    EndIf

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

    ; Shows the filenames of all files in the current directory.
    $searchPath = FileFindFirstFile("*.*")

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

    ; Check if the search was successful
    If $searchPath <> -1 Then

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

    ; Die innere Schleife wird durchlaufen, wenn Ordner in c:\pdfs vorhanden sind oder wenn Dateien in den Ordnern vorhanden sind.
    While 1

    ; Wenn das Script bereits länger als die in $restartZeit angegebene Zeit durchläuft, wird es neugestartet, um den Verbrauch an physischem Speicher,
    ; der mit der Zeit zunimmt, zu reduzieren
    $dif = TimerDiff($startZeit)
    if $dif > $restartZeit then
    $ret = Run(@ComSpec & ' /c start /MIN ' & 'pdf_spooler.exe', $envPath, @SW_HIDE, 2 + 4)
    Exit
    EndIf

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

    $currPath = FileFindNextFile($searchPath)
    If @error Then
    ; Schleife wird erneut mit erstem Ordner durchlaufen
    FileClose($searchPath)
    $searchPath = FileFindFirstFile("*.*")
    $currPath = FileFindNextFile($searchPath)
    EndIf
    $attr = FileGetAttrib($currPath)
    If StringInStr($attr,"D") Then

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

    ; Shows the filenames of all files in the current directory.
    $searchPdf = FileFindFirstFile($currPath & "\*.pdf")

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

    ; Die innere Schleife wird durchlaufen, wenn Dateien in den Unterordnern von c:\pdfs vorhanden sind.
    While 1
    $file = FileFindNextFile($searchPdf)
    If @error Then ExitLoop

    ; Der Acrobat Reader muss vor dem Druck geschlossen werden, da sonst nicht gedruckt werden kann
    $pid = "AcroRd32.exe"
    While ProcessExists($pid)
    ProcessClose($pid)
    WEnd

    ; Ausgabe mittels Pdfp-Tool, das den Adobe Reader ansteuert, auf Drucker, der als Pfadname angegeben ist
    $pdfpCommand = $envPath & '\' & $pdfpExe & ' -p "' & $printserver & '\' & $currPath & '" -c 1 "' & $envPath & '\' & $currPath & '\' & $file & '"'
    $statusText = ''
    $ret = Run(@ComSpec & ' /c start /MIN ' & $pdfpCommand, "", @SW_HIDE, 2 + 4)
    While 1
    $statusText &= StdoutRead($ret, False, False)
    If @error Then ExitLoop
    Sleep(10)
    WEnd

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

    DirCreate($currPath & "\save")

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

    ; Wenn bereits eine gleichnamige Datei existiert, soll diese durch die aktuelle Pdf-Datei in $file ersetzt werden.
    if FileExists($currPath & "\save\" & $file) Then
    FileDelete($currPath & "\save\" & $file)
    EndIf
    FileMove($currPath & "\" & $file, $currPath & "\save\" & $file)
    WEnd

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

    ; Close the search handle
    FileClose($searchPdf)

    EndIf
    Sleep($warteZyklus)
    WEnd
    FileClose($searchPath)
    EndIf
    Sleep($warteZyklus)
    WEnd

    [/autoit]

    Einmal editiert, zuletzt von Hanseat (15. Juni 2010 um 15:32)

  • Hi, vielleicht hilft StdioClose nach der StdOutRead-Schleife um den Speicherverbaruch zu reduzieren?

    PS: Verwende für so lange Skripte zusätzlich einen Spoiler, dann wird der Beitrag übersichtlicher.

  • danke, ich werde zunächst beide Möglichkeiten in Betracht ziehen und nochmal testen.

    2 Mal editiert, zuletzt von Hanseat (15. Juni 2010 um 15:32)

  • Mit StdioClose ist der Speicherverbrauch schonmal deutlich geringer! Zunächst habe ich ersteinmal die Neustartfunktion des Scriptes nach dem Timerintervall herausgenommen. Das Script lasse ich nun erstmal einen Tag laufen und werde dann nachsehen, ob es abgebrochen ist und wenn ja, warum. Vielen Dank.

    Philip

    Spoiler anzeigen
    [autoit]


    #Include <File.au3>

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

    $envPath = "c:\pdfs"
    $printserver = "\\nt-printserver"
    $pdfpExe = "pdfp.exe"
    $logFile = "pdfs.log"
    $spoolerFile = "pdf_spooler.exe"
    $restartZeit = 72000000 ; wartet x Stunden und startet dann das Skript erneut
    $warteZyklus = 500 ; zwischen den einzelnen Abtastzyklen existiert eine Pause von x Sekunden, um den physischen Speicher zu schonen

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

    WinSetState("System Properties","",@SW_HIDE)

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

    ; Umgebungsverzeichnis auf $envPath setzen
    FileChangeDir ($envPath)

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

    Opt("OnExitFunc", "endscript")

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

    Func endscript()
    ; Log-Datei zum Schreiben von Status öffnen
    $log = FileOpen("fehler.log", 1)
    FileWriteLine($log, @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @SEC & " Service beendet durch " & @EXITMETHOD & ". Fehler: " & @error)
    FileClose($log)
    EndFunc

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

    ; Wenn Logdatei noch nicht existiert, dann neu anlegen
    if Not FileExists($logFile) Then _FileCreate($logFile)

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

    ; Log-Datei zum Schreiben von Status öffnen
    $log = FileOpen($logFile, 1)

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

    ; Prüfen, ob ausreichend Speicherplatz (>=50 MBytes) auf der Festplatte vorhanden ist
    $freeSpace = DriveSpaceFree($envpath)
    If $freeSpace < 50 Then
    $errText = "Der freie Speicherplatz beträgt weniger als 50 MBytes. Programm wird beendet."
    ;MsgBox(0, "Error", $errText)
    FileWriteLine($log, $errText)
    FileClose($log)
    Exit
    EndIf

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

    FileWriteLine($log, @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @SEC & " Service gestartet.")
    FileClose($log)

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

    ; Die äußere Schleife wird durchlaufen, wenn keine Ordner in c:\pdfs vorhanden sind, Ordner vorhanden sind oder wenn Dateien in den Ordnern vorhanden sind.
    While 1

    ; Shows the filenames of all files in the current directory.
    $searchPath = FileFindFirstFile("*.*")

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

    ; Check if the search was successful
    If $searchPath <> -1 Then

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

    ; Die innere Schleife wird durchlaufen, wenn Ordner in c:\pdfs vorhanden sind oder wenn Dateien in den Ordnern vorhanden sind.
    While 1

    $currPath = FileFindNextFile($searchPath)
    If @error Then
    ; Schleife wird erneut mit erstem Ordner durchlaufen
    FileClose($searchPath)
    $searchPath = FileFindFirstFile("*.*")
    $currPath = FileFindNextFile($searchPath)
    EndIf
    $attr = FileGetAttrib($currPath)
    If StringInStr($attr,"D") Then

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

    ; Shows the filenames of all files in the current directory.
    $searchPdf = FileFindFirstFile($currPath & "\*.pdf")

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

    ; Die innere Schleife wird durchlaufen, wenn Dateien in den Unterordnern von c:\pdfs vorhanden sind.
    While 1
    $file = FileFindNextFile($searchPdf)
    If @error Then ExitLoop

    ; Der Acrobat Reader muss vor dem Druck geschlossen werden, da sonst nicht gedruckt werden kann
    $pid = "AcroRd32.exe"
    While ProcessExists($pid)
    ProcessClose($pid)
    WEnd

    ; Ausgabe mittels Pdfp-Tool, das den Adobe Reader ansteuert, auf Drucker, der als Pfadname angegeben ist
    $pdfpCommand = $envPath & '\' & $pdfpExe & ' -p "' & $printserver & '\' & $currPath & '" -c 1 "' & $envPath & '\' & $currPath & '\' & $file & '"'
    $statusText = ''
    $ret = Run(@ComSpec & ' /c start /MIN ' & $pdfpCommand, "", @SW_HIDE, 2 + 4)
    While 1
    $statusText &= StdoutRead($ret, False, False)
    If @error Then ExitLoop
    Sleep(10)
    WEnd
    StdioClose($ret)

    DirCreate($currPath & "\save")

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

    ; Wenn bereits eine gleichnamige Datei existiert, soll diese durch die aktuelle Pdf-Datei in $file ersetzt werden.
    if FileExists($currPath & "\save\" & $file) Then
    FileDelete($currPath & "\save\" & $file)
    EndIf
    FileMove($currPath & "\" & $file, $currPath & "\save\" & $file)
    WEnd

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

    ; Close the search handle
    FileClose($searchPdf)

    EndIf
    Sleep($warteZyklus)
    WEnd
    FileClose($searchPath)
    EndIf
    Sleep($warteZyklus)
    WEnd

    [/autoit]

    3 Mal editiert, zuletzt von Hanseat (15. Juni 2010 um 15:31)