rudi Posted November 11, 2009 Share Posted November 11, 2009 Hi.I wrote a small script, that has to copy a drive ALMOST up to it's rim.For doing so, I use the "\i386\" folder of the current windows installation's "sourcepath" from registry. (I always copy over the Win-Setup source files to HDD for any installation I'm doing...)With "Adlibenable("WipeOld",1000)" I wanted to check, if the free space on that drive drops below the size of the "\i386\" folder. If that should be fact, then delete the oldest one of the folders out there. Then the next copy step has enough free space to copy data over and over again, stressing the disks of a newly created host drive. (RAID)To get the result code of robocopy, I use a runwait("robocopy sourcedir nextdestdir switches switches")It looks like the adlibenabled function is never called? Maybe, adlibenable() is only executed, when1.) the given timeframe is met AND...2.) when the script is right now stepping from one line of code to the next one?Or maybe my usage of Adlibdisable() / Adlibenable() is the reason, why it's never executed, because (possibly) every time I do so the timer will start from "0", so that the 1000 ms can never be reached?Regards, Rudi.expandcollapse popup#include <array.au3> #include <date.au3> #include <file.au3> $ini = StringTrimRight(@ScriptFullPath, 3) & "ini" If Not FileExists($ini) Then $initxt = ";Beispiel INI Datei für " & @ScriptName & @CRLF $initxt &= @CRLF $initxt &= "; Mit dem Parameter StopAt=YYYY/MM/DD hh:mm:ss kann festgelegt werden, wann der Platten-Last Test selbsttätig beendet werden soll" & @CRLF $initxt &= "; Fehlt der Parameter, oder ist er ungültig, dann läuft der Test immer weiter" & @CRLF $initxt &= @CRLF $initxt &= "[parameters]" & @CRLF $initxt &= ";Mit diesem Beispiel werden ab 08. Nov. 2009, 06:30 Uhr keine neuen Kopierjobs mehr gestartet" & @CRLF $initxt &= ";StopAt=2009/11/08 06:30:00" & @CRLF FileWrite($ini, $initxt) EndIf $StopAt = IniRead($ini, "Parameters", "StopAt", "never") $Key = "hklm\software\microsoft\windows\currentversion\setup" $val = "Sourcepath" $Source = RegRead($Key, $val) $ScrDir = @ScriptDir If StringRight($ScrDir, 1) = "\" Then $ScrDir = StringTrimRight($ScrDir, 1) ; When started from a drive's root, @scriptdir will return a trailing "\" -> kick that one! FileInstall("Robocopy.exe", $ScrDir & "\RobocopyXP.exe") ; Robocopy version 010. Version 026 from Robocopy-GUI does *NOT* return exit codes any more!!! $Source = $Source & "\i386\" $Source = StringReplace($Source, "\\", "\") If StringLeft($Source, 1) = "\" Then $Source = "\" & $Source If Not StringInStr(FileGetAttrib($Source), "d", 0) Then ; source directory doesn't exist MsgBox(48, "Fehler", "Der für diese Windows Installation in der Registry angegebene Source Path kann nicht gelesen werden: " & @LF & _ $Source, 10) Exit EndIf $PlatzOrg = Ceiling(DirGetSize($Source) / 1024 / 1024) If $StopAt = "Never" Then $LabelPrefix = "Belastungstest läuft unbegrenzt weiter. Zum Beenden dieses Scirpt stoppen (Symbol im Systray)" & @CRLF & @CRLF Else $LabelPrefix = "Aus der INI gelesener Endzeitpunkt für den Belastungstest:" & @CRLF & $StopAt & @CRLF & @CRLF EndIf $LabelPrefix &= "Belastungstest für die Festplatten auf folgenden Pfad: " & @LF & $ScrDir & @LF & "Durchgang Nr.: " $i = 1 $fatal = False $Myi386 = $ScrDir & "\i386" If Not DirCreate($Myi386) Then MsgBox(48, "Fehler", "Kann Verzeichnis '" & $Myi386 & "' nicht anlegen") $fatal = True EndIf $LogPath = $ScrDir & "\Log-Files\" ConsoleWrite($ScrDir & @CRLF) $Free = DriveSpaceFree($ScrDir) $fatal = False If $Free < $PlatzOrg * 3.5 Then MsgBox(48, "Zu wenig Platz", "Zu wenig Platz frei, um einen sinnvollen Belastungstest auf" & @CRLF & $ScrDir & @CRLF & "durchführen zu können!" & @CRLF & _ "Frei : " & Ceiling($Free) & @CRLF & _ "Benötigt : " & Ceiling($PlatzOrg * 3.5), 20) $fatal = True EndIf If Not DirCreate($LogPath) Then MsgBox(48, "Ordner für LOG Dateien", "Der Ordner für die LOG Dateien kann nicht angelegt werden:" & @CRLF & $LogPath, 20) $fatal = True EndIf If $fatal Then MsgBox(64, "Fehler im Vorfeld", "Der Plattenbelastungstest konnte nicht ausgeführt werden, es sind Fehler im Vorfeld aufgetreten") Exit EndIf $w = 400 $h = 200 $MyWindow = GUICreate("Last auf Festplatten", $w, $h, @DesktopWidth - $w, 0) $label = GUICtrlCreateLabel($LabelPrefix & $i, 20, 20, $w - 40, $h - 40) GUISetState(@SW_SHOW) WinSetOnTop($MyWindow, "", 1) GUICtrlSetData($label, $LabelPrefix & "Estelle Grundkopie...") RunWait("robocopyxp " & $Source & " " & $Myi386 & " /mir /r:0 /w:0 /reg /np /log:" & $LogPath & "\Robocopy-000000.log /tee") $SammelLog=$LogPath & "Gesamt-Ergebnis.log" if FileExists($SammelLog) Then FileMove($SammelLog,StringTrimRight($SammelLog,3)& "-" & FileGetTime($SammelLog,0,1) & ".BAK") FileWriteLine($SammelLog,@crlf & @crlf & @crlf); 2 zeilen muss das Teil haben um bis Zeile 3 Einfügen zu können AdlibEnable("WipeOld", 1000) Dim $i = 0 Dim $DirArr[1] = [0] While 1 $i += 1 ; total number of runs $iStr = "00000" & $i $iStr = StringRight($iStr, 6) MakeNextDir() $Done = Round($i * $PlatzOrg / 1024, 2) If $Done > 100 Then $Done = Round($Done / 1024, 3) & " TB" Else $Done &= " GB" EndIf GUICtrlSetData($label, $LabelPrefix & $i & @CRLF & @CRLF & "Bisher kopiert: " & $Done) If $i = 1 Then ; create initial copy $result = RunWait("robocopyxp " & $Myi386 & " " & $DirArr[1] & " /mir /r:0 /w:0 /reg /np /log:" & $LogPath & "Robocopy-" & $iStr & ".log", "", @SW_HIDE) _FileWritetoLine($SammelLog, 1, "Plattentest begonnen: " & _NowCalc()) Else $result = RunWait("robocopyxp " & $DirArr[2] & " " & $DirArr[1] & " /mir /r:0 /w:0 /reg /np /log:" & $LogPath & "\Robocopy-" & $iStr & ".log", "", @SW_HIDE) EndIf If $result = 1 Then ; robocopy exit code: only new files have been copied. (no fails, no extra files, ...) _FileWritetoLine($SammelLog,2, " OK : Durchgang " & $i & ", " & _NowCalc()) Else _FileWritetoLine($SammelLog,2, "ExitCode = " & $result & " : Durchgang " & $i & ", " & _NowCalc()) EndIf If $StopAt <> "never" Then If _DateDiff('s', $StopAt, _NowCalc()) > 1 Then _FileWriteToLine($SammelLog, 2, "Plattentest beendet: " & _NowCalc() ) _FileWriteToLine($SammelLog,3,"Kopiertes Volumen: " & $Done) _FileWriteToLine($SammelLog, 4, "---------------------------------------------------------------------------------------------") run ("notepad " & $SammelLog) Exit EndIf EndIf WEnd Func MakeNextDir() AdlibDisable() ; here the wiping out of old data may *NOT* happen: it would mix up the array's content _ArrayAdd($DirArr, "") ; add "empty" element at the end of the array... $DirArr[0] = UBound($DirArr) - 1 For $shift = $DirArr[0] To 2 Step -1 ; move all elements one element to array's end: So the oldest folder is at the end. $DirArr[$shift] = $DirArr[$shift - 1] Next $DirArr[1] = $ScrDir & "\SammelDir\Durchlauf-" & $iStr AdlibEnable("wipeold") ; from now on the "WipeOld" may be executed again: Array changes are done. EndFunc ;==>MakeNextDir Func WipeOld() $Free = DriveSpaceFree($ScrDir) If $Free < $PlatzOrg * 1.3 Then ; Space is running short: delete oldest copy... DirRemove($DirArr[$DirArr[0]]) _ArrayDelete($DirArr, $DirArr[0]) $DirArr[0] = UBound($DirArr) - 1 EndIf EndFunc ;==>WipeOldRegards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
Tvern Posted November 11, 2009 Share Posted November 11, 2009 I can think of a few issues: 1. Robocopy doesn't shut down properly, making the script hang at "RunWait()" 2. AdlibEnable() takes 250ms to trigger by default. If your While loop takes less time than that it will disable and enable, resetting the timer again. (seems the more likely) Link to comment Share on other sites More sharing options...
martin Posted November 11, 2009 Share Posted November 11, 2009 (edited) 2. AdlibEnable() takes 250ms to trigger by default. If your While loop takes less time than that it will disable and enable, resetting the timer again. (seems the more likely)Adlib is set to operate every 1000ms or every second, so the default 250ms is not being used. The while doesn't need to end because as soon as the while loop starts the function MakeNextDir() is called and the adlib function is disabled.That will happen a fraction of a millisecond after AdlibEnble I expect. Edited November 11, 2009 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
rudi Posted November 12, 2009 Author Share Posted November 12, 2009 Hi.Adlib is set to operate every 1000ms or every second, so the default 250ms is not being used. The while doesn't need to end because as soon as the while loop starts the function MakeNextDir() is called and the adlib function is disabled.That will happen a fraction of a millisecond after AdlibEnble I expect.MakeNextDir() does a - adlibdisable() - create new destination directory - update the array - adlibenable() again.The following robocopy will take few minutes. (... in case there is enough free space. Otherwise it will return immediately with an error)It looks to me as if during the external program robocopy.exe is run, the autoit script itself is "sleeping", waiting for the "runwait('robocopy....')" to end, without executing the adlibenabled function every second?I've worked around this issue by starting a 2nd script watching the free space and doing the cleanup, but I'm hoping I'm using adlibenable() not correctly yet, so that I could do so from *ONE* script.Regards, Rudi Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
Authenticity Posted November 13, 2009 Share Posted November 13, 2009 You can use Run() instead, save the process id and check with ProcessExists() and the PID. This way, the Adlib function may have a chance to be executed. Link to comment Share on other sites More sharing options...
rudi Posted November 14, 2009 Author Share Posted November 14, 2009 Hi.You can use Run() instead, save the process id and check with ProcessExists() and the PID.I've thought of that, too. But I can't see how to catch the exit code of a program started through run() instead of runwait()?Regards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
Tvern Posted November 15, 2009 Share Posted November 15, 2009 Adlib is set to operate every 1000ms or every second, so the default 250ms is not being used.I was referring to the one inside the loop, but that doesn't seem to be the problem.Hi.I've thought of that, too. But I can't see how to catch the exit code of a program started through run() instead of runwait()?Regards, Rudi.I don't know robocopy, but I imagine you might be able to use StdoutRead(), or StderrRead()? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now