Programmlaufzeit

  • Hi, Ich befasse mich seit ca. einer Woche mit AutoIt.
    Habe schon einige Grundkentnisse erworben, indem ich z.B. das Buch "AutoIt leicht gemacht" gelesen habe.
    Die ersten kleineren Skripte habe ich auch schon geschrieben.

    Nun zu meiner Frage:
    Ich möchte ein Skript schreiben, dass wenn ich ein Programm starte ein Zähler zu laufen beginnt und sobald ich das
    Programm wieder schliesse wird ein Fenster geöffnet, welches mir anzeigt wie lange das Programm geöffnet war.
    Es sollte aber nicht bei allen Programmen gestartet werden sondern nur bei einer zuvor definierten Liste(z.B. in einer .ini Datei).

    Müsst mir nicht gleich das ganze skript vorlegen, sondern nur Anregungen geben, wie ich da vorgehen könnte.

    Vielen Dank für eure Hilfe
    Dinozzo

  • Du brauchst nicht unbedingt einen eigenen Timer zu starten.
    Für jeden Prozess merkt sich Windows die Startzeit.
    Wenn man diese ausliest (z.B. mit WMI) kann man ganz leicht die Laufzeit berechnen.
    Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <Date.au3>

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

    ; Listet alle Prozesse
    $list = ProcessList()
    for $i = 1 to $list[0][0]
    $iTime = ProcessGetRunTime($list[$i][1])
    If not @error Then ConsoleWrite($list[$i][0] & @TAB & $iTime & "s" & @CRLF)
    Next

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

    $aTime = ProcessGetRunTime("System")
    If Not @error Then MsgBox(0,"", $aTime)

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: ProcessGetRunTime()
    ; Description ...: Gibt die Laufzeit eines Prozesses zurück
    ; Syntax ........: ProcessGetRunTime($PID, Const[ $sReturnType = "s"])
    ; Parameters ....: $PID -
    ; Const $sReturnType - [optional] Rückgabetyp entsprechend Parameter $sType in _DateDiff() (default:"s")
    ; Return values .: Success: Laufzeit des Programmes
    ; Failure: Setzt @Error und Return=0
    ; Author ........: AspirinJunkie
    ; Related .......: WMIDateStringToDate
    ; =================================================================================================
    Func ProcessGetRunTime($PID, Const $sReturnType = "s")
    If IsString($PID) Then $PID = ProcessExists($PID)
    If $PID = 0 Then Return SetError(1, 0, 0)
    Local Static $oWMI = ObjGet("winmgmts:\\localhost\root\CIMV2")
    For $i In $oWMI.ExecQuery("SELECT CreationDate FROM Win32_Process WHERE ProcessID=" & $PID, "WQL", 0x10 + 0x20)
    Return Int(_DateDiff($sReturnType, WMIDateStringToDate($i.CreationDate), _NowCalc()))
    Next
    Return SetError(2, 0, 0)
    EndFunc ;==>ProcessGetCreationDate

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

    Func WMIDateStringToDate($dtmDate)
    Return (StringLeft($dtmDate, 4) & "/" & _
    StringMid($dtmDate, 5, 2) & "/" & StringMid($dtmDate, 7, 2) _
    & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2))
    EndFunc

    [/autoit]
  • Hallo Zusammen


    Wollte euch mal meine Lösung vorstellen:

    Programmlaufzeit.au3

    Spoiler anzeigen
    [autoit]

    #include <array.au3>

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

    $_Processlist = IniReadSection("Processlist.ini", "Processes")
    $_Name = IniReadSection("Processlist.ini", "Programmname")

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

    While 1
    Sleep(100)
    For $i = 1 To UBound($_Processlist,1) -1
    If ProcessExists($_Processlist[$i][1]) Then
    $_begin = TimerInit()
    ProcessWaitClose($_Processlist[$i][1])
    $_dif = TimerDiff($_begin)
    $_Zeitinh = Int($_dif/3600000)
    $_Zeitinmin = Round((($_dif/3600000)-$_Zeitinh)*60)
    $_Zeitinsec = Round((((($_dif/3600000)-$_Zeitinh)*60)-(Int((($_dif/3600000)-$_Zeitinh)*60)))*60)
    If $_Zeitinh = 1 Then
    $_h = "Stunde"
    Else
    $_h = "Stunden"
    EndIf
    If $_Zeitinmin = 1 Then
    $_min = "Minute"
    Else
    $_min = "Minuten"
    EndIf
    If $_Zeitinsec = 1 Then
    $_sec = "Sekunde"
    Else
    $_sec = "Sekunden"
    EndIf
    $_msgbox = MsgBox(64, "Prozesslaufzeit", $_Name[$i][1]&" war "&$_Zeitinh&" "&$_h&" "&$_Zeitinmin&" "&$_min&" und "&$_Zeitinsec&" "&$_sec&" in Betrieb")
    EndIf
    Next
    WEnd

    [/autoit]

    Processlist.ini

    Spoiler anzeigen

    [Processes]
    Process1=firefox.exe

    [Programmname]
    Name1=Mozilla Firefox

    Was meint ihr dazu?

    Mfg Dinozzo

  • Da ist allerdings ein kleiner Denkfehler drin. Bei einer Anwendung ist das ok und funktioniert so. Solltest du aber 2 oder mehr Anwendungen überwachen wollen dürftest du ein Problem haben. Dein Script nimmt den ersten ini eintrag und schaut ob der Prozess existiert. Falls ja wartet das Script bis der Prozess beendet wird. Startest du die anderen Programme jetzt auch noch werden diese erst berücksichtigt sobald das erste Programm beendet wurde. Das hat zwei fatale Auswirkungen. Erstens stimmt die Laufzeit des zweiten Programms nicht, zweitens kann es sein, dass das zweite Programm beendet wird bevor das erste beendet wird. In diesem Fall würde die Laufzeit überhaupt nicht berücksichtigt.

    Ein weiteres Problem könnte auftreten wenn du mehrere Prozesse mit dem gleichen Prozessnamen hast. Hier würde dein Script dann solange pausieren bis wirklich alle firefox.exe Prozesse beendet sind. Sicherer ist es nach der ProzessID zu gehen.

  • Hallo misterspeed

    Das mit der ProzessID ist keine schlechte idee. :thumbup: Werde ich mal versuchen.
    Aber wie kann ich machen, dass er sich die startzeit von zwei verschiedenen Prozessen merkt?
    Das Skript steht ja bei ProcesWaitClose.

    Danke für die Antwort

    Einmal editiert, zuletzt von Dinozzo (8. Dezember 2010 um 10:13)