jazzyjeff Posted October 19, 2016 Share Posted October 19, 2016 Hey All, I am working on a script that will estimate how much time is remaining in a loop. To go a bit deeper, the script scans multiple folders for the permissions and the saves those permissions in a log. What I am looking for is to get an estimation of how long it will take to finish checking all the directories for permissions. I have the percentage calculations correct, but I feel like the time is creeping up, rather than coming down. Here is my code for the script. expandcollapse popup#include <Array.au3> #include <File.au3> MsgBox(0,"Permissions Search","You will be prompted first to enter a location to scan the permissions, and then you will need to select a location to save the log file.") $fPath = FileSelectFolder("Select folder to search", "C:\") SplashTextOn("Permission Search","Scanning directories to search...",220,70) $arrayFolder = _FileListToArrayRec($fPath, "*", 14, 1, 0, 2) SplashOff() ;_ArrayDisplay($arrayFolder) Dim $arrayFinal[1][8] ;_ArrayDisplay($arrayFinal) $lPath = FileSelectFolder("Select where to save the log file", "C:\") $fOpen = FileOpen($lPath & "\Permissions_Log.csv",10) FileWriteLine($fOpen,"User or Group,Path Number,Path,Inherited by Directories,Inherited by Files,Inherit Only,Inherited from Parent") $percent = 0 $progress = ProgressOn("Permission Search", "Scanning Directory for permissions", $percent & "%","","",16) $timeTaken = TimerInit() $timeLoopEnd = 1; Estimating 1 second per loop for timer For $i = 1 To $arrayFolder[0] $percent = $i / $arrayFolder[0] * 100 ; Calculate the percentage $timeRemaining = $timeLoopEnd * ($arrayFolder[0] - $i) ; 1 less item to scan so the countdown should be less $timeRemaining = $timeRemaining / 1000 ; Update Time in milliseconds to seconds remaining If $timeRemaining >= 60 Then ; If estimated time is minutes $timeRemainingMinutes = Round($timeRemaining/60,0) $timeRemainingSeconds = Mod($timeRemaining,60) ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & $timeRemainingMinutes & " minutes and " & Round($timeRemainingSeconds,0) & " secs remaining" & @CRLF & $arrayFolder[$i]) ElseIf $timeRemaining >= 3600 Then ; If estimated time is hours $timeRemainingHours = Round(($timeRemaining/60)/60,0) $timeRemainingMinutes = Mod($timeRemaining,60) ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & $timeRemainingHours & " hours and " & Round($timeRemainingMinutes,0) & " minutes remaining" & @CRLF & $arrayFolder[$i]) Else ; If estimated time is seconds $timeRemainingSeconds = $timeRemaining ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & Round($timeRemainingSeconds,0) & " secs remaining" & @CRLF & $arrayFolder[$i]) EndIf $timeRemaining = 0 $timeLoopEnd = 0 $timeRemainingHours = 0 $timeRemainingMinutes = 0 $timeRemainingSeconds = 0 $timeLoopStart = TimerInit() ; Start calculating how long to complete a loop Local $iPID = Run(@ComSpec & ' /C cacls "' & $arrayFolder[$i] & '"', "", @SW_HIDE, $STDOUT_CHILD) ProcessWaitClose($iPID) Local $sOutput = StdoutRead($iPID) $sOutput = StringReplace($sOutput, $arrayFolder[$i], "") $sOutput = StringSplit($sOutput, @CR) If IsArray($sOutput) Then ;_ArrayDisplay($sOutput) Dim $array[$sOutput[0] + 1] For $x = 1 To $sOutput[0] ;MsgBox(0,$x,$sOutput[$x]) $y = StringStripWS($sOutput[$x],4) $y = StringStripCR($y) If StringLeft($y, 1) = " " Then StringTrimLeft($y,1) EndIf ;MsgBox(0,$x,$y) $array[$x] = $y If StringIsSpace($array[$x]) Or $array[$x] = "" Then _ArrayDelete($array,$x) ;_ArrayDisplay($array, $x & "Empty value - Before") If $x = UBound($array) Then $array[0] = UBound($array) -1 ExitLoop Else $x = $x - 1 EndIf EndIf Next ;_ArrayDisplay($array,"Array") For $z = 1 To $array[0] $string = StringSplit($array[$z],":") If IsArray($string) Then If $string[0] > 0 Then ;_ArrayDisplay($string,"String Array") _ArrayAdd($arrayFinal,$string[1],0); user name or group Else _ArrayAdd($arrayFinal,"Unknown user or group",0) EndIf Else _ArrayAdd($arrayFinal,"Unknown user or group",0) EndIf $v = UBound($arrayFinal) -1 $arrayFinal[$v][1] = $i ; ID Number $arrayFinal[$v][2] = $arrayFolder[$i] ; File Path If StringInStr($array[$z], "(CI)") Then $arrayFinal[$v][3] = 1; CI - Container Inherit... The ACE will be inherited by directories Else $arrayFinal[$v][3] = 0 EndIf If StringInStr($array[$z], "(OI)") Then $arrayFinal[$v][4] = 1; OI - Object Inherit... The ACE will be inherited by files Else $arrayFinal[$v][4] = 0 EndIf If StringInStr($array[$z], "(IO)") Then $arrayFinal[$v][5] = 1; IO - Inherit Only... The ACE does not apply to the current file/directory Else $arrayFinal[$v][5] = 0 EndIf If StringInStr($array[$z], "(ID)") Then $arrayFinal[$v][6] = 1; ID - Inheritrf... The ACE was inherited from the parent directory's ACL Else $arrayFinal[$v][6] = 0 EndIf $stringStrip = StringStripWS($array[$z],2) If StringRight($stringStrip, 1) = "N" Then ; The permissions set. e.g. None, Read, Write, Change, Full Control $arrayFinal[$v][7] = "None" ElseIf StringRight($stringStrip, 1) = "R" Then $arrayFinal[$v][7] = "Read" ElseIf StringRight($stringStrip, 1) = "W" Then $arrayFinal[$v][7] = "Write" ElseIf StringRight($stringStrip, 1) = "C" Then $arrayFinal[$v][7] = "Change" ElseIf StringRight($stringStrip, 1) = "F" Then $arrayFinal[$v][7] = "Full Control" Else $arrayFinal[$v][7] = "None" EndIf FileWriteLine($fOpen,$arrayFinal[$v][0] & "," & $arrayFinal[$v][1] & "," & $arrayFinal[$v][2] & "," & $arrayFinal[$v][3] & "," & $arrayFinal[$v][4] & "," & $arrayFinal[$v][5] & "," & $arrayFinal[$v][6] & "," & $arrayFinal[$v][7]) Next Else $array = $sOutput ;_ArrayDisplay($sOutput,$arrayFolder[$i]) EndIf $timeLoopEnd = TimerDiff($timeLoopStart) Next ProgressSet(100,"Scan Complete",$arrayFolder[0] & " of " & $arrayFolder[0]) FileClose($fOpen) ProgressOff() $timer = TimerDiff($timeTaken) / 1000 If $timer >= 60 Then $timerMinutes = Round($timer/60, 0) $timerSeconds = Mod($timer, 60) If $timerMinutes > 1 Then MsgBox(0,"Complete","The permission scan is complete." & @CR & @CRLF & "The log file is located here: " & $lPath & "\Permissions_Log.csv" & @CR & @CRLF & "Time taken: " & $timerMinutes & " minutes and " & $timerSeconds & " seconds." ) Else MsgBox(0,"Complete","The permission scan is complete." & @CR & @CRLF & "The log file is located here: " & $lPath & "\Permissions_Log.csv" & @CR & @CRLF & "Time taken: " & $timerMinutes & " minute and " & $timerSeconds & " seconds." ) EndIf Else MsgBox(0,"Complete","The permission scan is complete." & @CR & @CRLF & "The log file is located here: " & $lPath & "\Permissions_Log.csv" & @CR & @CRLF & "Time taken: " & $timerSeconds & " seconds." ) EndIf _ArrayDisplay($arrayFinal,"Final Array") This is the part of the script that is probably of interest for the time calculations. $timeLoopEnd = 1; Estimating 1 second per loop for timer For $i = 1 To $arrayFolder[0] $percent = $i / $arrayFolder[0] * 100 ; Calculate the percentage $timeRemaining = $timeLoopEnd * ($arrayFolder[0] - $i) ; 1 less item to scan so the countdown should be less $timeRemaining = $timeRemaining / 1000 ; Update Time in milliseconds to seconds remaining If $timeRemaining >= 60 Then ; If estimated time is minutes $timeRemainingMinutes = Round($timeRemaining/60,0) $timeRemainingSeconds = Mod($timeRemaining,60) ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & $timeRemainingMinutes & " minutes and " & Round($timeRemainingSeconds,0) & " secs remaining" & @CRLF & $arrayFolder[$i]) ElseIf $timeRemaining >= 3600 Then ; If estimated time is hours $timeRemainingHours = Round(($timeRemaining/60)/60,0) $timeRemainingMinutes = Mod($timeRemaining,60) ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & $timeRemainingHours & " hours and " & Round($timeRemainingMinutes,0) & " minutes remaining" & @CRLF & $arrayFolder[$i]) Else ; If estimated time is seconds $timeRemainingSeconds = $timeRemaining ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & Round($timeRemainingSeconds,0) & " secs remaining" & @CRLF & $arrayFolder[$i]) EndIf I understand this more of a math problem, but I am having a hard time figuring it out. I'm hoping another set of eyes will be able to help. Thanks, Jeff Link to comment Share on other sites More sharing options...
BrewManNH Posted October 19, 2016 Share Posted October 19, 2016 It would be FAR easier to just use a progress bar without trying to figure out the time remaining too. Ever heard of Microsoft Time? I haven't seen an OS or program that gets the time remaining accurate enough to ever really pay attention to it. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
RTFC Posted October 19, 2016 Share Posted October 19, 2016 (edited) Hi Jazzyjeff. One mistake you're making is in the conversions to minutes and hours. First you round to minutes or hours (which may go up or down), and then you calculate the remainder (as if you always rounded down). So use Floor or Int instead there. Edited October 19, 2016 by RTFC My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O Link to comment Share on other sites More sharing options...
jazzyjeff Posted October 19, 2016 Author Share Posted October 19, 2016 haha BrewManNH. Yes, I know the time isn't going to be terribly accurate, but it gives a rough idea of how long you may have to wait. Thanks RTFC. I will look at that and see how it works. Link to comment Share on other sites More sharing options...
corgano Posted October 19, 2016 Share Posted October 19, 2016 You could just timerinit() when you started, and at any point $timesofar = timerdiff($inittime) $timesofar / 100 * (100 - $percentDone) = approx time remaining It won't be accurate for any task that runs at a non-linear speed, but for a rough idea it should work. 0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e Link to comment Share on other sites More sharing options...
jazzyjeff Posted October 20, 2016 Author Share Posted October 20, 2016 Well, I got the time counting down, and it was "sort of close". Well I mean it started out at 80 minutes and it finished with 13 minutes to go :-) Here is the final code I had. I'm going to try an tweak it a little further, but it seems a pain to do so I won't worry about it too much more. At the end it tells me how long it ran which is nice. Thanks for everyone's input. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=C:\Temp\Permission Finder.Exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <Array.au3> #include <File.au3> MsgBox(0,"Permissions Search","You will be prompted first to enter a location to scan the permissions, and then you will need to select a location to save the log file.") $fPath = FileSelectFolder("Select folder to search", "C:\") SplashTextOn("Permission Search","Scanning directories to search...",220,70) $arrayFolder = _FileListToArrayRec($fPath, "*", 14, 1, 0, 2) SplashOff() ;_ArrayDisplay($arrayFolder) Dim $arrayFinal[1][8] ;_ArrayDisplay($arrayFinal) $lPath = FileSelectFolder("Select where to save the log file", "C:\") $fOpen = FileOpen($lPath & "\Permissions_Log.csv",10) FileWriteLine($fOpen,"User or Group,Path Number,Path,Inherited by Directories,Inherited by Files,Inherit Only,Inherited from Parent") $percent = 0 $progress = ProgressOn("Permission Search", "Scanning Directory for permissions", $percent & "%","","",16) $timeTaken = TimerInit() $timeLoopEnd = 0.4; Estimating time in second per loop for timer on initial launch $timeStarted = @HOUR & ":" & @MIN & ":" & @SEC For $i = 1 To $arrayFolder[0] $percent = $i / $arrayFolder[0] * 100 ; Calculate the percentage If $i = 1 Then $timeRemaining = $arrayFolder[0];$timeLoopEnd* ($arrayFolder[0]) Else $timeLoopEnd = $timeLoopEnd/1000 $timeRemaining = $timeRemaining-$timeLoopEnd EndIf ;$timeRemaining = $timeRemaining / 1000 ; Update Time in milliseconds to seconds remaining If $timeRemaining >= 60 Then ; If estimated time is minutes $timeRemainingMinutes = Int($timeRemaining)/60 $timeRemainingSeconds = Mod($timeRemaining,60) ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & Round($timeRemainingMinutes,0) & " minutes and " & Round($timeRemainingSeconds,0) & " secs remaining" & @CRLF & $arrayFolder[$i]) ElseIf $timeRemaining >= 3600 Then ; If estimated time is hours $timeRemainingHours = (Int($timeRemaining)/60)/60 $timeRemainingMinutes = Mod($timeRemaining,60) ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & Round($timeRemainingHours,0) & " hours and " & Round($timeRemainingMinutes,0) & " minutes remaining" & @CRLF & $arrayFolder[$i]) Else ; If estimated time is seconds $timeRemainingSeconds = $timeRemaining ProgressSet($percent,$i & " of " & $arrayFolder[0] & " - " & Round($percent,1) & "% - " & Round($timeRemainingSeconds,0) & " secs remaining" & @CRLF & $arrayFolder[$i]) EndIf $timeLoopEnd = 0 $timeRemainingHours = 0 $timeRemainingMinutes = 0 $timeRemainingSeconds = 0 $timeLoopStart = TimerInit() ; Start calculating how long to complete a loop Local $iPID = Run(@ComSpec & ' /C cacls "' & $arrayFolder[$i] & '"', "", @SW_HIDE, $STDOUT_CHILD) ProcessWaitClose($iPID) Local $sOutput = StdoutRead($iPID) $sOutput = StringReplace($sOutput, $arrayFolder[$i], "") $sOutput = StringSplit($sOutput, @CR) If IsArray($sOutput) Then ;_ArrayDisplay($sOutput) Dim $array[$sOutput[0] + 1] For $x = 1 To $sOutput[0] ;MsgBox(0,$x,$sOutput[$x]) $y = StringStripWS($sOutput[$x],4) $y = StringStripCR($y) If StringLeft($y, 1) = " " Then StringTrimLeft($y,1) EndIf ;MsgBox(0,$x,$y) $array[$x] = $y If StringIsSpace($array[$x]) Or $array[$x] = "" Then _ArrayDelete($array,$x) ;_ArrayDisplay($array, $x & "Empty value - Before") If $x = UBound($array) Then $array[0] = UBound($array) -1 ExitLoop Else $x = $x - 1 EndIf EndIf Next ;_ArrayDisplay($array,"Array") For $z = 1 To $array[0] $string = StringSplit($array[$z],":") If IsArray($string) Then If $string[0] > 0 Then ;_ArrayDisplay($string,"String Array") _ArrayAdd($arrayFinal,$string[1],0); user name or group Else _ArrayAdd($arrayFinal,"Unknown user or group",0) EndIf Else _ArrayAdd($arrayFinal,"Unknown user or group",0) EndIf $v = UBound($arrayFinal) -1 $arrayFinal[$v][1] = $i ; ID Number $arrayFinal[$v][2] = $arrayFolder[$i] ; File Path If StringInStr($array[$z], "(CI)") Then $arrayFinal[$v][3] = 1; CI - Container Inherit... The ACE will be inherited by directories Else $arrayFinal[$v][3] = 0 EndIf If StringInStr($array[$z], "(OI)") Then $arrayFinal[$v][4] = 1; OI - Object Inherit... The ACE will be inherited by files Else $arrayFinal[$v][4] = 0 EndIf If StringInStr($array[$z], "(IO)") Then $arrayFinal[$v][5] = 1; IO - Inherit Only... The ACE does not apply to the current file/directory Else $arrayFinal[$v][5] = 0 EndIf If StringInStr($array[$z], "(ID)") Then $arrayFinal[$v][6] = 1; ID - Inheritrf... The ACE was inherited from the parent directory's ACL Else $arrayFinal[$v][6] = 0 EndIf $stringStrip = StringStripWS($array[$z],2) If StringRight($stringStrip, 1) = "N" Then ; The permissions set. e.g. None, Read, Write, Change, Full Control $arrayFinal[$v][7] = "None" ElseIf StringRight($stringStrip, 1) = "R" Then $arrayFinal[$v][7] = "Read" ElseIf StringRight($stringStrip, 1) = "W" Then $arrayFinal[$v][7] = "Write" ElseIf StringRight($stringStrip, 1) = "C" Then $arrayFinal[$v][7] = "Change" ElseIf StringRight($stringStrip, 1) = "F" Then $arrayFinal[$v][7] = "Full Control" Else $arrayFinal[$v][7] = "None" EndIf $stringFinal = StringStripCR($arrayFinal[$v][0] & "," & $arrayFinal[$v][1] & "," & $arrayFinal[$v][2] & "," & $arrayFinal[$v][3] & "," & $arrayFinal[$v][4] & "," & $arrayFinal[$v][5] & "," & $arrayFinal[$v][6] & "," & $arrayFinal[$v][7]) $stringFinal = StringStripWS($stringFinal,3) FileWriteLine($fOpen,$stringFinal) Next Else $array = $sOutput ;_ArrayDisplay($sOutput,$arrayFolder[$i]) EndIf $timeLoopEnd = TimerDiff($timeLoopStart) Next ProgressSet(100,"Scan Complete",$arrayFolder[0] & " of " & $arrayFolder[0]) FileClose($fOpen) ProgressOff() $timer = TimerDiff($timeTaken) / 1000 If $timer >= 60 Then $timerMinutes = Round($timer/60, 0) $timerSeconds = Mod($timer, 60) If $timerMinutes > 1 Then MsgBox(0,"Complete","The permission scan is complete." & @CR & @CRLF & "The log file is located here: " & $lPath & "\Permissions_Log.csv" & @CR & @CRLF & "Time Started: " & $timeStarted & @CRLF & "Time Finished: " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & "Time taken: " & $timerMinutes & " minutes and " & Round($timerSeconds,0) & " seconds." ) ElseIf $timerMinutes > 60 Then $timerHours = Floor($timerMinutes) $timerMinutes = Mod($timerMinutes,60) MsgBox(0,"Complete","The permission scan is complete." & @CR & @CRLF & "The log file is located here: " & $lPath & "\Permissions_Log.csv" & @CR & @CRLF & "Time Started: " & $timeStarted & @CRLF & "Time Finished: " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & "Time taken: " & $timerHours & " hours and " & Round($timerMinutes,0) & " minutes." ) Else MsgBox(0,"Complete","The permission scan is complete." & @CR & @CRLF & "The log file is located here: " & $lPath & "\Permissions_Log.csv" & @CR & @CRLF & "Time Started: " & $timeStarted & @CRLF & "Time Finished: " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & "Time taken: " & $timerMinutes & " minute and " & Round($timerSeconds,0) & " seconds." ) EndIf Else MsgBox(0,"Complete","The permission scan is complete." & @CR & @CRLF & "The log file is located here: " & $lPath & "\Permissions_Log.csv" & @CR & @CRLF & "Time Started: " & $timeStarted & @CRLF & "Time Finished: " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & "Time taken: " & Round($timer,0) & " seconds." ) EndIf _ArrayDisplay($arrayFinal,"Final Array") 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