StdoutRead auslesen

  • Hallo zusammen

    Aus dem englischen Forum habe ich diese feinen Zeilen entdeckt. So rein nach Msgbox funktioniert das StdoutRead Auslesen gut. Nur die Progressbar bleibt bei 0% zeigt nichts an, und schliesst sich auch nicht wenn der kopiervorgang beendet ist ?(

    [autoit]

    #include <Constants.au3>
    $sourcedir = "c:\test\"
    $destdir = "c:\tocopy2\"
    $result=""
    $ourProcess = Run (@ComSpec & " /c " & 'robocopy.exe ' & $sourcedir & ' ' & $destdir & ' /E /NJH /NJS /NDL /NC', @ScriptDir, @SW_HIDE, $STDOUT_CHILD)
    ProgressOn("RoboCopy", "Copying Files...", "0%",-1,-1,18)
    While 1
    If $ourProcess Then
    $charsWaiting = StdoutRead($ourProcess, 0 , 1)
    If @error = -1 Then
    $ourProcess = 0
    MsgBox(0, "App Exited", "Process has exited...")
    ContinueLoop
    EndIf
    ;While 1
    ; $line = StdoutRead($ourProcess)
    ; If @error Then ExitLoop
    ; MsgBox(0, "STDOUT read:", $line)
    ;Wend
    If $charsWaiting Then
    $currentRead = StdoutRead($ourProcess)
    $fileinfo = StringRegExp($currentRead, '(.*?)([:alpha:]:.*\.[a-zA-Z]{3})',3)
    If IsArray($fileinfo) = 1 Then
    $filesize = StringStripCR(StringStripWS($fileinfo[0],8))
    $filename = $fileinfo[1]
    EndIf
    $percent = StringRegExp($currentRead, '([0-9]{1,3})(?:.[0-9]{1,3})(?:%)',3)
    If IsArray($percent) = 1 Then
    ProgressSet($percent[0],$percent[0]&"% "&@CRLF&"Filename: "&$filename&@CRLF&"Filesize: "&$filesize)
    EndIf
    If IsArray($result) Then
    If StringInStr($result[0], "%") Then; Current line is a progress update line
    $progress = StringTrimRight($result[0], 1)
    MsgBox (4096,"Test", $progress)
    EndIf
    EndIf
    EndIf
    EndIf
    WEnd
    ProgressOff()
    Exit

    [/autoit]

    Sieht jemand den Fehler? Das wäre genau der Script, den ich gerade gut gebrauchen könnte ;)

  • Hallo TheLuBu

    While 1
    $line = StdoutRead($currentRead)
    If @error Then ExitLoop
    MsgBox(0, "STDOUT read:", $currentRead)
    Wend

    ergibt einfach gar nichts, wenn ich das an Zeile 28 einfüge. Wenn ich nur MsgBox(0, "STDOUT read:", $currentRead) einpflanze, dann erhalte ich eine leere Msgbox.


    Aber wie kann $currentread leer sein? Das mit dem auslesen klappt doch prinzipiell, was meine auskommentierte Msgbox aus Post1 auch zeigt...

  • Ich versteh an dem Skript einige Sachen nicht.
    Warum rufst du Robocopy nicht direkt auf sondern über die cmd.exe?
    Was sollen die mehreren StdOutReads ($charswaiting und $currentread)?
    Warum keine @error-Abfrage hinter dem 2. StdOutRead?
    Warum wird das erste StdOutRead() binär behandelt und nicht als Text?
    Hast du mal die Ergebnisse der StringRegExp()-Aufrufe ausgegeben ob die überhaupt greifen?

  • Füg mal das hier

    [autoit]

    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $currentRead = ' & $currentRead & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit]


    Bei Zeile 22 ein, den Wert wollte ich wissen ;)

  • Ich gebs auf.
    Ignorier halt weiter meine Fragen...

    Ich hatte mal ein ähnliches Skript geschrieben daher das hier als mein letzter Vorschlag:

    Spoiler anzeigen
    [autoit]

    #include <Constants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>

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

    #region Tray-Menü

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

    TrayCreateItem("Beenden")
    TrayItemSetOnEvent(-1, "RoboCopyClose")
    TrayCreateItem("Wiederherstellen")
    TrayItemSetOnEvent(-1, "RoboCopyRestore")
    TraySetState()
    #endregion Tray-Menü

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

    #region GUI
    Global $hGUI = GUICreate("RoboCopy", 399, 98, 192, 124)
    GUISetOnEvent($GUI_EVENT_CLOSE, "RoboCopyClose")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "RoboCopyMinimize")
    Global $Label1 = GUICtrlCreateLabel("Verzeichnis:", 8, 12, 61, 17)
    Global $Label2 = GUICtrlCreateLabel("Datei", 32, 44, 29, 17)
    Global $Label3 = GUICtrlCreateLabel("Kopiere", 24, 74, 40, 17, $SS_RIGHT)
    Global $Label4 = GUICtrlCreateLabel("99.9%", 360, 72, 33, 17, $SS_RIGHT)
    Global $Label5 = GUICtrlCreateLabel("Größe", 284, 44, 33, 17)
    Global $Label6 = GUICtrlCreateLabel("mb", 376, 44, 18, 17)

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

    Global $Input1 = GUICtrlCreateInput("", 72, 8, 321, 21)
    Global $Input2 = GUICtrlCreateInput("", 72, 40, 209, 21)
    Global $Input3 = GUICtrlCreateInput("", 320, 40, 49, 21)

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

    Global $Progress1 = GUICtrlCreateProgress(72, 72, 281, 17)
    #endregion GUI
    OnAutoItExitRegister("raus")

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

    Global $bBreak = False, $bMac = False, $bMin = False, $bDelFolds = False, $iPID

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

    _Robocopy("c:\test\", "c:\tocopy2\")

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

    ; Funktion _Robocopy()
    ; - kopiert ein Verzeichnis a nach b mit Unterordnern und zeigt den momentanen Bearbeitungsstand
    Func _Robocopy($sVon, $sNach, $bDelDirs = False)
    Local $sline, $sErrLine, $sFile, $sSize
    Local $aRegExp, $a_Temp
    Local $sFile, $sFileold = '', $sSize, $sSizeold = 0, $iFort, $iFortold = -1, $sDirold = ''
    Local $sParameters

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

    If $bDelDirs = True Then
    $sParameters = ' /MIR /W:1 /R:1 /A-:HS /XJD /XA:SH'
    Else
    $sParameters = ' /E /W:1 /R:1 /A-:HS /XJD /XA:SH'
    EndIf

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

    GUISetState(@SW_SHOW)

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

    ; Nur Anführungszeichen wenn Leerzeichen vorkommt:
    If StringInStr($sVon, " ") Then $sVon = '"' & $sVon & '"'
    If StringInStr($sNach, " ") Then $sNach = '"' & $sNach & '"'

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

    $iPID = Run('Robocopy ' & $sVon & ' ' & $sNach & $sParameters, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    If @error Then Return MsgBox(0,"Fehler", "Fehlercode: " & @error & @CRLF & "PID: " & $iPID)

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

    $bBreak = False

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

    While 1
    If $bBreak Then
    GUICtrlSetData($Input1, "Prozess wird beendet...")
    Do
    ProcessClose($iPID)
    Until ProcessExists($iPID) = 0
    GUIDelete($hGUI)
    Exit
    EndIf

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

    If $bMin Then
    GUISetState(@SW_HIDE, $hGUI)
    EndIf

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

    $sline = StdoutRead($iPID)
    If @error Then ExitLoop

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

    If $sline <> '' Then
    For $i In StringSplit($sline, @CRLF, 2)
    #region Dateiname und Größe ermitteln
    $aRegExp = StringRegExp($i, '(?m)^\s+(New File|Newer|Neuer|Neue Datei|Älter|Older)\s+([\d\.]+?)\s?([mg]?)\t([^\n\r]+?)$', 4)
    If Not @error Then
    $a_Temp = $aRegExp[0]

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

    $sFile = $a_Temp[4]
    $sSize = Number($a_Temp[2])

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

    Switch $a_Temp[1]
    Case 'New File', 'Neue Datei'
    If GUICtrlRead($Label3) <> 'Kopiere' Then GUICtrlSetData($Label3, 'Kopiere')
    Case 'Newer', 'Neuer'
    If GUICtrlRead($Label3) <> 'Aktualisiere' Then GUICtrlSetData($Label3, 'Aktualisiere')
    EndSwitch

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

    Switch StringRight($sSize, 1)
    Case 'm'
    $sSize = $sSize
    Case 'g'
    $sSize = Round($sSize * 1024, 1)
    Case Else
    $sSize = Round($sSize / 1048576, 2)
    EndSwitch

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

    TraySetToolTip($sFile)

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

    GUICtrlSetData($Input2, $sFile)
    GUICtrlSetData($Input3, $sSize)
    EndIf
    #endregion Dateiname und Größe ermitteln

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

    #region Fortschritt ermitteln
    $aRegExp = StringRegExp($i, '(?m)^\s*([\d\.]+)%\s*?$', 3)
    If Not @error Then
    $iFort = Number($aRegExp[0])
    If $iFort <> $iFortold Then
    $iFortold = $iFort
    GUICtrlSetData($Progress1, $iFort)
    GUICtrlSetData($Label4, $iFort & '%')
    EndIf
    If $iFort = 100 Then GUICtrlSetData($Input2, "... suche ...")
    EndIf
    #endregion Fortschritt ermitteln

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

    #region aktuelles Verzeichnis ermitteln
    $aRegExp = StringRegExp($i, '(?m)\d+\s+?([A-Z]:[^\n\r\t\?]+?\\)\s*?$', 3)
    If Not @error Then
    If $aRegExp[0] <> $sDirold Then
    $sDirold = $aRegExp[0]
    GUICtrlSetData($Input1, $aRegExp[0])
    EndIf
    EndIf
    #endregion aktuelles Verzeichnis ermitteln
    Next
    EndIf
    Sleep(1)
    WEnd

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

    GUISetState(@SW_HIDE, $hGUI)
    Return $sErrLine
    EndFunc ;==>_Robocopy

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

    Func RoboCopyClose()
    $bBreak = True
    EndFunc ;==>RoboCopyClose

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

    Func RoboCopyMinimize()
    $bMin = True
    EndFunc ;==>RoboCopyMinimize

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

    Func RoboCopyRestore()
    $bMin = False
    GUISetState(@SW_SHOW, $hGUI)
    EndFunc ;==>RoboCopyRestore

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

    Func raus()
    ProcessClose($iPID)
    Run("taskkill /pid " & $iPID)
    EndFunc ;==>raus

    [/autoit]

    Edit: Oh entschuldigt Surfy und TheLuBu. Hab euch beide verwechselt und gedacht die Posts kommen von einer Person...
    Sorry

  • Danke Dir Adrenalinjunkie. Aber dein Script ist viel zu komplex für meinen Skill. Und daher bekomme ich das erst recht nicht zum laufen.

    Der kleine Script den ich da gefunden / gepostet habe, der wäre genau passend

  • Also gut, mal als Frage, wie groß sind die Dateien, die du kopieren willst?
    Robocopy arbeitet so schnell, das es nur wirklich mit Dateien größer als 50MB lohnt, einen Progress festzuhalten.
    Wenn du da jetzt nur ein paar Txt Dateien drin hast, dann zeigt er dir nix an, weil er schon fertig ist, bis die Funktion von Autoit greift ;)

    Desweiteren hast du eine Endlosschleife, mit Continueloop setzt du die Schleife fort, da müsste Exitloop stehen

  • Danke für deine Hilfe!

    Es sind 177 GB an Daten, mit einer Dateigrösse von mini bis zu 2 GB.

    Das mit dem Exitloop war schon ein klasse tip!

    Das Hochzählen und anzeigen, klappt hingehen nicht :-/ Ich probiers nun mal mit XXL Dateien

    Einmal editiert, zuletzt von Surfy (13. Juli 2011 um 14:35)