jvanegmond Posted October 28, 2009 Posted October 28, 2009 Suggestion: - Run 10 ping commands at one time. The nice thing of having them in a different process is that you can do it asynchronously. - Set parameters on the ping command to specify a number of repetitions and timeout. - Check out the AutoIt source code, to see how the Ping() works in the underlying C++ code. github.com/jvanegmond
cherdeg Posted October 28, 2009 Author Posted October 28, 2009 Yes, it does.So WTF ?!? I could not be any more clueless than I currently am...can you imagine anything on a random XP machine causing this?
jvanegmond Posted October 28, 2009 Posted October 28, 2009 No, and as far as I know you're the first to experience this problem. I am going to write you an alternative, because I am bored and you really deserve an answer after all your efforts. github.com/jvanegmond
jvanegmond Posted October 28, 2009 Posted October 28, 2009 (edited) Here. I didn't want to confuse you with what parts belong to the _MSPing "library" and what is part of the script using the library. So I didn't use any functions in the script that uses the library, was kind of a pain and I had to do stuff like ExitLoop 2 but I hope you still understand it.expandcollapse popup#include <Constants.au3> #include <Array.au3> #cs ; Simple example: $a_ping = _MSPing("localhost") While (Not _MSPingIsReady($a_ping)) Sleep(250) WEnd $pingtime = _MSPingGetResult($a_ping) MsgBox(0,"", "Ping time: " & $pingtime) #ce ; Async example Local Const $MAX_PROCESS = 10 ; We spawn a maximum of 10 processes at once Local $a_process[$MAX_PROCESS] ; An array to keep a reference to spawned processes, in the next loop we fill it with value 0 For $i = 0 to UBound($a_process)-1 $a_process[$i] = 0 Next ; The following array represents a list of hosts, these are probably provided from a file later on Local $address[100] For $i = 0 to 99 $address[$i] = "74.125.45." & $i+1 ; We generate some IPs Next ConsoleWrite("Pinging " & UBound($address) & " addresses." & @CRLF) Local $i = 0 ; A pointer to run through the $address array While True ; Check on the current processes, and look if there is one finished for use with our next host in line (from $address) For $n = 0 to UBound($a_process)-1 If ($a_process[$n] == 0) Then ; Check if there is an empty spot ; There is an empty spot ConsoleWrite("Pinging " & $address[$i] & " ... " & @CRLF) $a_process[$n] = _MSPing($address[$i]) $i += 1 If ($i == UBound($address)) Then ExitLoop 2 EndIf Else ; Something is running here, let's check on the output If (_MSPingIsReady($a_process[$n])) Then ; We have an output here, let's get it! $hostname = _MSPingGetHostname($a_process[$n]) $pingtime = _MSPingGetResult($a_process[$n]) If ($pingtime <> -1) Then ConsoleWrite($hostname & " has a roundtrip of " & $pingtime & "." & @CRLF) Else ConsoleWrite($hostname & " is unreachable." & @CRLF) EndIf ; Free up an empty space for the next address to Ping $a_process[$n] = 0 EndIf EndIf Next Sleep(50) ; Give existing ping commands some time to process the request WEnd ConsoleWrite("Ping ready!!" & @CRLF) Func _MSPing($hostname, $timeout = 50) Local $return_struc[4] ; [0] = Result (in ms) ; [1] = The hostname originally used ; [2] = Process handle (for internal use only) ; [3] = Buffer (for internal use only) $return_struc[1] = $hostname $return_struc[2] = Run("ping " & $hostname & " -n 1 -w " & $timeout, "", @SW_HIDE, $STDOUT_CHILD) Return $return_struc EndFunc Func _MSPingIsReady(ByRef $return_struc) Return ___MSPingReadOutput($return_struc) EndFunc Func _MSPingGetResult($return_struc) Return $return_struc[0] EndFunc Func _MSPingGetHostname($return_struc) Return $return_struc[1] EndFunc ; Internal use only Func ___MSPingReadOutput(ByRef $return_struc) $data = StdoutRead($return_struc[2]) If (@error) Then ___MSPingParseResult($return_struc) Return 1 Else $return_struc[3] &= $data Return 0 EndIf EndFunc ; Internal use only Func ___MSPingParseResult(ByRef $return_struc) $result = StringRegExp($return_struc[3], "([0-9]*)ms", 3) If @error Then $return_struc[0] = -1 Else $return_struc[0] = $result[0] EndIf EndFuncOutput:expandcollapse popupPinging 100 addresses. Pinging 74.125.45.1 ... Pinging 74.125.45.2 ... Pinging 74.125.45.3 ... Pinging 74.125.45.4 ... Pinging 74.125.45.5 ... Pinging 74.125.45.6 ... Pinging 74.125.45.7 ... Pinging 74.125.45.8 ... Pinging 74.125.45.9 ... Pinging 74.125.45.10 ... 74.125.45.6 has a roundtrip of 116. 74.125.45.4 has a roundtrip of 116. 74.125.45.5 has a roundtrip of 116. Pinging 74.125.45.11 ... 74.125.45.9 has a roundtrip of 116. Pinging 74.125.45.12 ... Pinging 74.125.45.13 ... Pinging 74.125.45.14 ... 74.125.45.1 is unreachable. 74.125.45.2 is unreachable. 74.125.45.3 is unreachable. 74.125.45.12 is unreachable. 74.125.45.13 is unreachable. 74.125.45.11 is unreachable. 74.125.45.7 is unreachable. 74.125.45.8 is unreachable. 74.125.45.14 is unreachable. 74.125.45.10 is unreachable. Pinging 74.125.45.15 ... Pinging 74.125.45.16 ... Pinging 74.125.45.17 ... Pinging 74.125.45.18 ... Pinging 74.125.45.19 ... Pinging 74.125.45.20 ... Pinging 74.125.45.21 ... Pinging 74.125.45.22 ... Pinging 74.125.45.23 ... Pinging 74.125.45.24 ... 74.125.45.16 has a roundtrip of 115. Pinging 74.125.45.25 ... 74.125.45.18 has a roundtrip of 114. 74.125.45.17 has a roundtrip of 115. Pinging 74.125.45.26 ... 74.125.45.19 has a roundtrip of 115. Pinging 74.125.45.27 ... Pinging 74.125.45.28 ... 74.125.45.15 is unreachable. 74.125.45.25 is unreachable. 74.125.45.20 is unreachable. 74.125.45.21 is unreachable. 74.125.45.22 is unreachable. 74.125.45.23 is unreachable. 74.125.45.24 is unreachable. Pinging 74.125.45.29 ... Pinging 74.125.45.30 ... 74.125.45.26 is unreachable. Pinging 74.125.45.31 ... Pinging 74.125.45.32 ... Pinging 74.125.45.33 ... Pinging 74.125.45.34 ... Pinging 74.125.45.35 ... Pinging 74.125.45.36 ... 74.125.45.34 has a roundtrip of 115. 74.125.45.36 has a roundtrip of 115. 74.125.45.32 has a roundtrip of 115. 74.125.45.33 has a roundtrip of 114. Pinging 74.125.45.37 ... 74.125.45.35 has a roundtrip of 116. Pinging 74.125.45.38 ... Pinging 74.125.45.39 ... Pinging 74.125.45.40 ... Pinging 74.125.45.41 ... 74.125.45.29 is unreachable. 74.125.45.30 is unreachable. 74.125.45.27 is unreachable. 74.125.45.28 is unreachable. 74.125.45.31 is unreachable. 74.125.45.37 is unreachable. Pinging 74.125.45.42 ... Pinging 74.125.45.43 ... Pinging 74.125.45.44 ... Pinging 74.125.45.45 ... Pinging 74.125.45.46 ... Pinging 74.125.45.47 ... 74.125.45.39 has a roundtrip of 115. 74.125.45.38 has a roundtrip of 114. Pinging 74.125.45.48 ... 74.125.45.40 has a roundtrip of 115. 74.125.45.41 has a roundtrip of 115. 74.125.45.42 has a roundtrip of 114. Pinging 74.125.45.49 ... Pinging 74.125.45.50 ... Pinging 74.125.45.51 ... Pinging 74.125.45.52 ... 74.125.45.43 has a roundtrip of 114. 74.125.45.44 has a roundtrip of 115. 74.125.45.45 has a roundtrip of 115. 74.125.45.47 has a roundtrip of 117. Pinging 74.125.45.53 ... Pinging 74.125.45.54 ... Pinging 74.125.45.55 ... 74.125.45.46 has a roundtrip of 115. Pinging 74.125.45.56 ... Pinging 74.125.45.57 ... 74.125.45.51 is unreachable. 74.125.45.52 is unreachable. 74.125.45.49 is unreachable. 74.125.45.48 is unreachable. 74.125.45.50 is unreachable. Pinging 74.125.45.58 ... Pinging 74.125.45.59 ... Pinging 74.125.45.60 ... Pinging 74.125.45.61 ... Pinging 74.125.45.62 ... 74.125.45.53 has a roundtrip of 114. 74.125.45.54 has a roundtrip of 115. Pinging 74.125.45.63 ... Pinging 74.125.45.64 ... 74.125.45.57 has a roundtrip of 115. 74.125.45.56 has a roundtrip of 115. Pinging 74.125.45.65 ... Pinging 74.125.45.66 ... 74.125.45.58 has a roundtrip of 114. 74.125.45.59 has a roundtrip of 115. 74.125.45.60 has a roundtrip of 115. 74.125.45.61 has a roundtrip of 114. 74.125.45.62 has a roundtrip of 115. Pinging 74.125.45.67 ... Pinging 74.125.45.68 ... 74.125.45.63 has a roundtrip of 114. 74.125.45.64 has a roundtrip of 115. Pinging 74.125.45.69 ... Pinging 74.125.45.70 ... Pinging 74.125.45.71 ... Pinging 74.125.45.72 ... Pinging 74.125.45.73 ... 74.125.45.55 is unreachable. 74.125.45.65 is unreachable. 74.125.45.66 is unreachable. Pinging 74.125.45.74 ... Pinging 74.125.45.75 ... Pinging 74.125.45.76 ... 74.125.45.68 has a roundtrip of 115. 74.125.45.69 has a roundtrip of 116. Pinging 74.125.45.77 ... 74.125.45.72 has a roundtrip of 115. 74.125.45.73 has a roundtrip of 115. Pinging 74.125.45.78 ... Pinging 74.125.45.79 ... Pinging 74.125.45.80 ... 74.125.45.74 has a roundtrip of 115. 74.125.45.75 has a roundtrip of 115. Pinging 74.125.45.81 ... Pinging 74.125.45.82 ... 74.125.45.76 has a roundtrip of 115. Pinging 74.125.45.83 ... 74.125.45.77 has a roundtrip of 115. 74.125.45.79 is unreachable. 74.125.45.80 is unreachable. 74.125.45.78 has a roundtrip of 115. 74.125.45.81 is unreachable. 74.125.45.82 is unreachable. 74.125.45.70 is unreachable. 74.125.45.71 is unreachable. 74.125.45.67 is unreachable. Pinging 74.125.45.84 ... Pinging 74.125.45.85 ... Pinging 74.125.45.86 ... Pinging 74.125.45.87 ... Pinging 74.125.45.88 ... Pinging 74.125.45.89 ... Pinging 74.125.45.90 ... Pinging 74.125.45.91 ... Pinging 74.125.45.92 ... 74.125.45.83 has a roundtrip of 115. Pinging 74.125.45.93 ... 74.125.45.84 has a roundtrip of 115. 74.125.45.85 has a roundtrip of 116. 74.125.45.86 has a roundtrip of 115. 74.125.45.91 has a roundtrip of 115. Pinging 74.125.45.94 ... Pinging 74.125.45.95 ... Pinging 74.125.45.96 ... Pinging 74.125.45.97 ... 74.125.45.93 has a roundtrip of 115. 74.125.45.87 is unreachable. 74.125.45.88 is unreachable. 74.125.45.89 is unreachable. 74.125.45.90 is unreachable. Pinging 74.125.45.98 ... 74.125.45.92 is unreachable. Pinging 74.125.45.99 ... Pinging 74.125.45.100 ... Ping ready!!Takes about 4 seconds to ping 100 hosts. It can be faster if you allow more processes to be spawned. Edited October 28, 2009 by Manadar github.com/jvanegmond
cherdeg Posted October 28, 2009 Author Posted October 28, 2009 I am going to write you an alternative, because I am bored and you really deserve an answer after all your efforts.You would really do that? That's completely incredible. I need to inform you that here at work I have the problem also exists on hosts with Vista and Server 2003...but on my XP machine at home everything works.
jvanegmond Posted October 28, 2009 Posted October 28, 2009 You would really do that? That's completely incredible. I need to inform you that here at work I have the problem also exists on hosts with Vista and Server 2003...but on my XP machine at home everything works.Right above your post. github.com/jvanegmond
cherdeg Posted October 28, 2009 Author Posted October 28, 2009 Right above your post. Wow. Something forces you to heave me to the next level in AutoIT programming, right? That code is, ummm, simply great (as fas as I understand it)! I'd never thought it possible to control Microsoft's ping that way...
jvanegmond Posted October 28, 2009 Posted October 28, 2009 Wow. Something forces you to heave me to the next level in AutoIT programming, right? That code is, ummm, simply great (as fas as I understand it)! I'd never thought it possible to control Microsoft's ping that way...I guess I did feel the need to force you to the next level. Personally, I was more satisfied with the way that the next ping command could start, while the others are still working. But that's just me.Enjoy this code. Maybe it has changed your mind about this forums support and me.. 8) github.com/jvanegmond
cherdeg Posted October 28, 2009 Author Posted October 28, 2009 Enjoy this code. Maybe it has changed your mind about this forums support and me.. 8) I do enjoy, Manadar. Although I still don't understand completely. And: You're actually not the one I criticize: my rant primarily was targeted at November and ProgAndi. You and I had a misunderstanding, nothing more or less... I've modified your code a little to use it as a function. I've noticed that one has to set $MAX_PROCESS to a value lower than the number of hosts to process. For, e.g., google.com, I set it to 1 (which of course destroys the async mode). When setting a higher value (2 or 3), the results are not displayed. But even if I set it to 1, the result for the last host is missing. Is there a chance to get it? expandcollapse popup#include <Constants.au3> #include <Array.au3> Local $s_MailRelayFQDN = "google.com" Local $a_IPs = _LookupIPs($s_MailRelayFQDN) ConsoleWrite("Pinging " & UBound($a_IPs) & " addresses:" & @CRLF & @CRLF) $a_IPsChecked = _CheckOnlineStatus($a_IPs, 1) $a_OnlineIPs = $a_IPsChecked[0] If IsArray($a_OnlineIPs) Then _ArraySort($a_OnlineIPs, "", "", "", 1) _ArrayDisplay($a_OnlineIPs) ConsoleWrite(@CRLF & "The currently fastest host is: " & $a_OnlineIPs[0][0] & @CRLF) Else ConsoleWrite(@CRLF & "None of the hosts was online!!!" & @CRLF) EndIf ConsoleWrite(@CRLF & "Ping ready!!!" & @CRLF) ; Function Name _LookupIPs() ; ================================================================================================== ; ; Function Name: _CheckOnlineStatus() ; Description: Checks if hosts are online or not ; Parameter(s): $a_Hostnames, $i_MaxProcess ; Requirement(s): AutoIt 3.3 ; Return Value(s): Two arrays containing: ; a) the hostnames of the hosts that are online ; b) the hostnames of the hosts that are offline ; Author(s): Manadar ; ; ================================================================================================== Func _CheckOnlineStatus($a_Hostnames, $i_MaxProcess) ; Prepare the asynchronous execution Local Const $MAX_PROCESS = $i_MaxProcess ; We spawn a maximum of 8 processes at once Local $a_process[$MAX_PROCESS] ; An array to keep a reference to spawned processes, in the next loop we fill it with value 0 For $i = 0 To UBound($a_process) - 1 $a_process[$i] = 0 Next Local $a_tmpOnHosts[1][2] ; The array to receive the hosts ONline Local $a_tmpOffHosts[1][2] ; The array to receive the hosts OFFline Local $i = 0 ; A pointer to run through the $a_Hostnames array While True ; Check on the current processes, and look if there is one finished for use with our next host in line (from $a_Hostnames) For $n = 0 To UBound($a_process) - 1 If ($a_process[$n] == 0) Then ; Check if there is an empty spot ; There is an empty spot ConsoleWrite("Pinging " & $a_Hostnames[$i] & " ... " & @CRLF) $a_process[$n] = _MSPing($a_Hostnames[$i]) $i += 1 If ($i == UBound($a_Hostnames)) Then ExitLoop 2 EndIf Else ; Something is running here, let's check on the output If (_MSPingIsReady($a_process[$n])) Then ; We have an output here, let's get it! $s_hostname = _MSPingGetHostname($a_process[$n]) $i_pingtime = _MSPingGetResult($a_process[$n]) If ($i_pingtime <> -1) Then ConsoleWrite($s_hostname & " has a roundtrip of " & $i_pingtime & "." & @CRLF) Local $a_TempAdd[2] = [$s_hostname, $i_pingtime] _2DArrayAdd($a_tmpOnHosts, $a_TempAdd, False) Else ConsoleWrite($s_hostname & " is unreachable." & @CRLF) Local $a_TempAdd[2] = [$s_hostname, $i_pingtime] _2DArrayAdd($a_tmpOffHosts, $a_TempAdd, False) EndIf ; Free up an empty space for the next address to Ping $a_process[$n] = 0 EndIf EndIf Next Sleep(100) ; Give existing ping commands some time to process the request WEnd ; Delete record 0 of the temporary arrays _ArrayDelete($a_tmpOnHosts, 0) _ArrayDelete($a_tmpOffHosts, 0) ; Save both the temporary arrays to a transport array... Local $a_Hosts[2] $a_Hosts[0] = $a_tmpOnHosts $a_Hosts[1] = $a_tmpOffHosts ; ...return the transport array back to main() Return $a_Hosts EndFunc ;==>_CheckOnlineStatus ; Function Name _LookupIPs() ; ================================================================================================== ; ; Function Name: _LookupIPs() ; Description: Gets the IPs of a given FQDN ; Parameter(s): $s_FQDN ; Requirement(s): AutoIt 3.2.10.0 ; Return Value(s): An array containing the IP(s) resolved for the given FQDN ; Author(s): cs/IT solutions ; ; ================================================================================================== Func _LookupIPs($s_FQDN) ; Setup and execute the command and fetch the STDout-data it produces $s_STDoutData = _RunReadStd("nslookup " & $s_FQDN, 0, @WorkingDir, 0, 1, @LF) ; Put the data to an array $a_tmp = StringSplit($s_STDoutData, @CRLF, 2) ; Delete the unneeded first 3 records For $i = 1 To 3 _ArrayDelete($a_tmp, 0) Next ; Add all records to a new string; remove the words "Address" or "Addresses" Local $s_tmp For $i = 0 To UBound($a_tmp) - 1 $s_tmp &= StringReplace(StringReplace(StringStripWS($a_tmp[$i], 8), "Address:", ""), "Addresses:", "") If $i < UBound($a_tmp) - 1 Then $s_tmp &= "," Next ; Split the string to an array $a_IPs = StringSplit($s_tmp, ",", 2) ; Return the array Return $a_IPs EndFunc ;==>_LookupIPs ; Function Name _RunReadStd() ; ================================================================================================== ; ; Function Name: _RunReadStd() ; Description:: Run a specified command, and return the Exitcode, StdOut text and ; StdErr text from from it. StdOut and StdErr are @tab delimited, ; with blank lines removed. ; Parameter(s): $doscmd: the actual command to run, same as used with Run command ; $timeoutSeconds: maximum execution time in seconds, optional, default: 0 (wait forever), ; $workingdir: directory in which to execute $doscmd, optional, default: @ScriptDir ; $flag: show/hide flag, optional, default: @SW_HIDE ; $sDelim: stdOut and stdErr output deliminter, optional, default: @TAB ; $nRetVal: return single item from function instead of array, optional, default: -1 (return array) ; Requirement(s): AutoIt 3.2.10.0 ; Return Value(s): An array with three values, Exit Code, StdOut and StdErr ; Author(s): lod3n ; (Thanks to mrRevoked for delimiter choice and non array return selection) ; (Thanks to mHZ for _ProcessOpenHandle() and _ProcessGetExitCode()) ; (MetaThanks to DaveF for posting these DllCalls in Support Forum) ; (MetaThanks to JPM for including CloseHandle as needed) ; ; ================================================================================================== Func _RunReadStd($doscmd, $timeoutSeconds = 0, $workingdir = @ScriptDir, $flag = @SW_HIDE, $nRetVal = -1, $sDelim = @TAB) Local $aReturn, $i_Pid, $h_Process, $i_ExitCode, $sStdOut, $sStdErr, $runTimer Dim $aReturn[3] ; run process with StdErr and StdOut flags $runTimer = TimerInit() $i_Pid = Run($doscmd, $workingdir, $flag, 6) ; 6 = $STDERR_CHILD+$STDOUT_CHILD ; Get process handle Sleep(100) ; or DllCall may fail - experimental $h_Process = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $i_Pid) ; create tab delimited string containing StdOut text from process $aReturn[1] = "" $sStdOut = "" While 1 $sStdOut &= StdoutRead($i_Pid) If @error Then ExitLoop WEnd $sStdOut = StringReplace($sStdOut, @CR, @TAB) $sStdOut = StringReplace($sStdOut, @LF, @TAB) $aStdOut = StringSplit($sStdOut, @TAB, 1) For $i = 1 To $aStdOut[0] $aStdOut[$i] = StringStripWS($aStdOut[$i], 3) If StringLen($aStdOut[$i]) > 0 Then $aReturn[1] &= $aStdOut[$i] & $sDelim EndIf Next $aReturn[1] = StringTrimRight($aReturn[1], 1) ; create tab delimited string containing StdErr text from process $aReturn[2] = "" $sStdErr = "" While 1 $sStdErr &= StderrRead($i_Pid) If @error Then ExitLoop WEnd $sStdErr = StringReplace($sStdErr, @CR, @TAB) $sStdErr = StringReplace($sStdErr, @LF, @TAB) $aStderr = StringSplit($sStdErr, @TAB, 1) For $i = 1 To $aStderr[0] $aStderr[$i] = StringStripWS($aStderr[$i], 3) If StringLen($aStderr[$i]) > 0 Then $aReturn[2] &= $aStderr[$i] & $sDelim EndIf Next $aReturn[2] = StringTrimRight($aReturn[2], 1) ; kill the process if it exceeds $timeoutSeconds If $timeoutSeconds > 0 Then If TimerDiff($runTimer) / 1000 > $timeoutSeconds Then ProcessClose($i_Pid) EndIf EndIf ; fetch exit code and close process handle If IsArray($h_Process) Then Sleep(100) ; or DllCall may fail - experimental $i_ExitCode = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $h_Process[0], 'int*', 0) If IsArray($i_ExitCode) Then $aReturn[0] = $i_ExitCode[2] Else $aReturn[0] = -1 EndIf Sleep(100) ; or DllCall may fail - experimental DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $h_Process[0]) Else $aReturn[0] = -2 EndIf ; return single item if correctly specified with with $nRetVal If $nRetVal <> -1 And $nRetVal >= 0 And $nRetVal <= 2 Then Return $aReturn[$nRetVal] ; return array with exit code, stdout, and stderr Return $aReturn EndFunc ;==>_RunReadStd ; Function Name _MSPing() ; ================================================================================================== Func _MSPing($hostname, $timeout = 50) Local $return_struc[4] ; [0] = Result (in ms) ; [1] = The hostname originally used ; [2] = Process handle (for internal use only) ; [3] = Buffer (for internal use only) $return_struc[1] = $hostname $return_struc[2] = Run("ping " & $hostname & " -n 1 -w " & $timeout, "", @SW_HIDE, $STDOUT_CHILD) Return $return_struc EndFunc ;==>_MSPing ; Function Name _MSPingIsReady() ; ================================================================================================== Func _MSPingIsReady(ByRef $return_struc) Return ___MSPingReadOutput($return_struc) EndFunc ;==>_MSPingIsReady ; Function Name _MSPingGetResult() ; ================================================================================================== Func _MSPingGetResult($return_struc) Return $return_struc[0] EndFunc ;==>_MSPingGetResult ; Function Name _MSPingGetHostname() ; ================================================================================================== Func _MSPingGetHostname($return_struc) Return $return_struc[1] EndFunc ;==>_MSPingGetHostname ; Function Name ___MSPingReadOutput() ; ================================================================================================== ; Internal use only Func ___MSPingReadOutput(ByRef $return_struc) $data = StdoutRead($return_struc[2]) If (@error) Then ___MSPingParseResult($return_struc) Return 1 Else $return_struc[3] &= $data Return 0 EndIf EndFunc ;==>___MSPingReadOutput ; Function Name ___MSPingParseResult() ; ================================================================================================== ; Internal use only Func ___MSPingParseResult(ByRef $return_struc) $result = StringRegExp($return_struc[3], "([0-9]*)ms", 3) If @error Then $return_struc[0] = -1 Else $return_struc[0] = $result[0] EndIf EndFunc ;==>___MSPingParseResult ; Function __ArrayAdd to add lines to a two-dimensional array ; ============================================================================================== Func _2DArrayAdd(ByRef $avArray, $vValue, $NestArray = True) Local $iBoundArray0, $iBoundArray1, $iBoundArray2, $iBoundValue1 ; $avArray is not an array If IsArray($avArray) = 0 Then Return SetError(1, 0, -1) ; No. of dimesions in array $iBoundArray0 = UBound($avArray, 0) ; $avArray is more than 2D If $iBoundArray0 > 2 Then Return SetError(1, 1, -1) ; Size of array in first dimension $iBoundArray1 = UBound($avArray, 1) ; Size of array in second dimension If $iBoundArray0 = 2 Then $iBoundArray2 = UBound($avArray, 2) ; If input array is 1D, or $vValue is not an array, or $NestArray = True (default) then save $vValue literally If ($iBoundArray0 = 1) Or (IsArray($vValue) = 0) Or $NestArray Then If $iBoundArray0 = 1 Then ; Add to 1D array ReDim $avArray[$iBoundArray1 + 1] $avArray[$iBoundArray1] = $vValue Else ; Add to 2D array at [n][0] ReDim $avArray[$iBoundArray1 + 1][$iBoundArray2] $avArray[$iBoundArray1][0] = $vValue EndIf Else ; If input array is 2D, and $vValue is an array, and $NestArray = False, ; then $vValue is a 1D array of values to add as a new row. ; $vValue array is not 1D If UBound($vValue, 0) <> 1 Then Return SetError(1, 2, -1) $iBoundValue1 = UBound($vValue, 1) ; $vValue array has too many elements If $iBoundArray2 < $iBoundValue1 Then Return SetError(1, 3, -1) ReDim $avArray[$iBoundArray1 + 1][$iBoundArray2] For $n = 0 To $iBoundValue1 - 1 $avArray[$iBoundArray1][$n] = $vValue[$n] Next EndIf ; Return index of new last row in $avArray Return $iBoundArray1 EndFunc ;==>__ArrayAdd
jvanegmond Posted October 28, 2009 Posted October 28, 2009 I know what's going wrong. The "thread" finished when all tasks have been started, and not when all tasks have been finished. I'll take a look if you want, but that'll have to be tonight or tomorrow. github.com/jvanegmond
cherdeg Posted October 29, 2009 Author Posted October 29, 2009 I'll take a look if you want, but that'll have to be tonight or tomorrow.That would be great...everything else is working perfect and blazingly fast.
jvanegmond Posted October 29, 2009 Posted October 29, 2009 I modified my own example, because I couldn't find the time to try and understand what you had done to mine. The important part is the ending changed from: Pinging 74.125.45.94 ... Pinging 74.125.45.95 ... Pinging 74.125.45.96 ... Pinging 74.125.45.97 ... 74.125.45.93 has a roundtrip of 115. 74.125.45.87 is unreachable. 74.125.45.88 is unreachable. 74.125.45.89 is unreachable. 74.125.45.90 is unreachable. Pinging 74.125.45.98 ... 74.125.45.92 is unreachable. Pinging 74.125.45.99 ... Pinging 74.125.45.100 ... Ping ready!! To: Pinging 74.125.45.95 ... Pinging 74.125.45.96 ... 74.125.45.89 is unreachable. Pinging 74.125.45.97 ... Pinging 74.125.45.98 ... 74.125.45.91 is unreachable. Pinging 74.125.45.99 ... Pinging 74.125.45.100 ... 74.125.45.93 has a roundtrip of 115. 74.125.45.96 has a roundtrip of 115. 74.125.45.98 has a roundtrip of 114. 74.125.45.95 has a roundtrip of 115. 74.125.45.97 has a roundtrip of 115. 74.125.45.99 has a roundtrip of 114. 74.125.45.100 has a roundtrip of 114. 74.125.45.92 is unreachable. 74.125.45.94 is unreachable. Ping ready!! Code: expandcollapse popup#include <Constants.au3> #include <Array.au3> #cs ; Simple example: $a_ping = _MSPing("localhost") While (Not _MSPingIsReady($a_ping)) Sleep(250) WEnd $pingtime = _MSPingGetResult($a_ping) MsgBox(0,"", "Ping time: " & $pingtime) #ce ; Async example Local Const $MAX_PROCESS = 10 ; We spawn a maximum of 10 processes at once Local $a_process[$MAX_PROCESS] ; An array to keep a reference to spawned processes, in the next loop we fill it with value 0 For $i = 0 to UBound($a_process)-1 $a_process[$i] = 0 Next ; The following array represents a list of hosts, these are probably provided from a file later on Local $address[100] For $i = 0 to 99 $address[$i] = "74.125.45." & $i+1 ; We generate some IPs Next ConsoleWrite("Pinging " & UBound($address) & " addresses." & @CRLF) Local $i = 0 ; A pointer to run through the $address array Local $finished = 0 ; <==== New line While True ; Check on the current processes, and look if there is one finished for use with our next host in line (from $address) For $n = 0 to UBound($a_process)-1 If ($i <> UBound($address) AND $a_process[$n] == 0) Then ; Check if we need a spot, and there is an existing spot ; There is an empty spot ConsoleWrite("Pinging " & $address[$i] & " ... " & @CRLF) $a_process[$n] = _MSPing($address[$i]) $i += 1 ; === This is wrong === ;If ($i == UBound($address)) Then ; ExitLoop 2 ;EndIf ; === This was wrong === Else ; Something is running here, let's check on the output If ($a_process[$n] <> 0 And _MSPingIsReady($a_process[$n])) Then ; We have an output here, let's get it! $hostname = _MSPingGetHostname($a_process[$n]) $pingtime = _MSPingGetResult($a_process[$n]) If ($pingtime <> -1) Then ConsoleWrite($hostname & " has a roundtrip of " & $pingtime & "." & @CRLF) Else ConsoleWrite($hostname & " is unreachable." & @CRLF) EndIf ; Free up an empty space for the next address to Ping $a_process[$n] = 0 $finished += 1 ; <=== New line If ($finished == UBound($address)) Then ExitLoop 2 ; Return EndIf EndIf EndIf Next Sleep(50) ; Give existing ping commands some time to process the request WEnd ConsoleWrite("Ping ready!!" & @CRLF) Func _MSPing($hostname, $timeout = 50) Local $return_struc[4] ; [0] = Result (in ms) ; [1] = The hostname originally used ; [2] = Process handle (for internal use only) ; [3] = Buffer (for internal use only) $return_struc[1] = $hostname $return_struc[2] = Run("ping " & $hostname & " -n 1 -w " & $timeout, "", @SW_HIDE, $STDOUT_CHILD) Return $return_struc EndFunc Func _MSPingIsReady(ByRef $return_struc) Return ___MSPingReadOutput($return_struc) EndFunc Func _MSPingGetResult($return_struc) Return $return_struc[0] EndFunc Func _MSPingGetHostname($return_struc) Return $return_struc[1] EndFunc ; Internal use only Func ___MSPingReadOutput(ByRef $return_struc) $data = StdoutRead($return_struc[2]) If (@error) Then ___MSPingParseResult($return_struc) Return 1 Else $return_struc[3] &= $data Return 0 EndIf EndFunc ; Internal use only Func ___MSPingParseResult(ByRef $return_struc) $result = StringRegExp($return_struc[3], "([0-9]*)ms", 3) If @error Then $return_struc[0] = -1 Else $return_struc[0] = $result[0] EndIf EndFunc github.com/jvanegmond
cherdeg Posted October 29, 2009 Author Posted October 29, 2009 (edited) I modified my own example, because I couldn't find the time to try and understand what you had done to mine. Your changes are perfect, everything works as supposed by now. BTW: I've done nothing hard to understand. I wrapped your code into a function, added the "return-two-arrays"-stuff, where I use 2D-arrays to have records of IP and pingtime and put everything together. Outside the function I sort the array of online hosts after the column containing the pingtimes, so the host in record[0][0] has to be the one reachable fastest. Here the complete code again: expandcollapse popup#AutoIt3Wrapper_Change2CUI=y #include <Constants.au3> #include <Array.au3> Local $s_MailRelayFQDN = "google.com" Local $a_IPs = _LookupIPs($s_MailRelayFQDN) ConsoleWrite("Pinging " & UBound($a_IPs) & " addresses:" & @CRLF & @CRLF) $a_IPsChecked = _CheckOnlineStatus($a_IPs, 4) $a_OnlineIPs = $a_IPsChecked[0] If IsArray($a_OnlineIPs) Then _ArraySort($a_OnlineIPs, "", "", "", 1) _ArrayDisplay($a_OnlineIPs) ConsoleWrite(@CRLF & "The currently fastest host is: " & $a_OnlineIPs[0][0] & @CRLF) Else ConsoleWrite(@CRLF & "None of the hosts was online!!!" & @CRLF) EndIf ConsoleWrite(@CRLF & "Ping ready!!!" & @CRLF) ; Function Name _LookupIPs() ; ================================================================================================== ; ; Function Name: _CheckOnlineStatus() ; Description: Checks if hosts are online or not ; Parameter(s): $a_Hostnames, $i_MaxProcess ; Requirement(s): AutoIt 3.3 ; Return Value(s): Two arrays containing: ; a) the hostnames of the hosts that are online ; b) the hostnames of the hosts that are offline ; Author(s): Manadar ; ; ================================================================================================== Func _CheckOnlineStatus($a_Hostnames, $i_MaxProcess) ; Prepare the asynchronous execution Local Const $MAX_PROCESS = $i_MaxProcess ; We spawn a maximum of 8 processes at once Local $a_process[$MAX_PROCESS] ; An array to keep a reference to spawned processes, in the next loop we fill it with value 0 For $i = 0 To UBound($a_process) - 1 $a_process[$i] = 0 Next Local $a_tmpOnHosts[1][2] ; The array to receive the hosts ONline Local $a_tmpOffHosts[1][2] ; The array to receive the hosts OFFline Local $i = 0 ; A pointer to run through the $a_Hostnames array Local $i_finished = 0 While True ; Check on the current processes, and look if there is one finished for use with our next host in line (from $a_Hostnames) For $n = 0 To UBound($a_process) - 1 If ($i <> UBound($a_Hostnames) And $a_process[$n] == 0) Then ; Check if we need a spot, and there is an existing spot ; There is an empty spot ConsoleWrite("Pinging " & $a_Hostnames[$i] & " ... " & @CRLF) $a_process[$n] = _MSPing($a_Hostnames[$i]) $i += 1 Else ; Something is running here, let's check on the output If ($a_process[$n] <> 0 And _MSPingIsReady($a_process[$n])) Then ; We have an output here, let's get it! $s_hostname = _MSPingGetHostname($a_process[$n]) $i_pingtime = _MSPingGetResult($a_process[$n]) If ($i_pingtime <> -1) Then ; Do some command line output and add hostnamen / pingtime to a 2D-array ConsoleWrite($s_hostname & " has a roundtrip of " & $i_pingtime & "." & @CRLF) Local $a_TempAdd[2] = [$s_hostname, $i_pingtime] _2DArrayAdd($a_tmpOnHosts, $a_TempAdd, False) Else ; Do some command line output and add hostnamen / pingtime to a 2D-array ConsoleWrite($s_hostname & " is unreachable." & @CRLF) Local $a_TempAdd[2] = [$s_hostname, $i_pingtime] _2DArrayAdd($a_tmpOffHosts, $a_TempAdd, False) EndIf ; Free up an empty space for the next address to ping $a_process[$n] = 0 $i_finished += 1 If ($i_finished == UBound($a_Hostnames)) Then ExitLoop 2 ; Return EndIf EndIf EndIf Next Sleep(50) ; Give existing ping commands some time to process the request WEnd ; Delete record 0 of the temporary arrays, we don't need the count _ArrayDelete($a_tmpOnHosts, 0) _ArrayDelete($a_tmpOffHosts, 0) ; Save both the temporary arrays to a transport array... Local $a_Hosts[2] $a_Hosts[0] = $a_tmpOnHosts $a_Hosts[1] = $a_tmpOffHosts ; ...return the transport array back to main() Return $a_Hosts EndFunc ;==>_CheckOnlineStatus ; Function Name _LookupIPs() ; ================================================================================================== ; ; Function Name: _LookupIPs() ; Description: Gets the IPs of a given FQDN ; Parameter(s): $s_FQDN ; Requirement(s): AutoIt 3.2.10.0 ; Return Value(s): An array containing the IP(s) resolved for the given FQDN ; Author(s): cs/IT solutions ; ; ================================================================================================== Func _LookupIPs($s_FQDN) ; Setup and execute the command and fetch the STDout-data it produces $s_STDoutData = _RunReadStd("nslookup " & $s_FQDN, 0, @WorkingDir, 0, 1, @LF) ; Put the data to an array $a_tmp = StringSplit($s_STDoutData, @CRLF, 2) ; Delete the unneeded first 3 records For $i = 1 To 3 _ArrayDelete($a_tmp, 0) Next ; Add all records to a new string; remove the words "Address" or "Addresses" Local $s_tmp For $i = 0 To UBound($a_tmp) - 1 $s_tmp &= StringReplace(StringReplace(StringStripWS($a_tmp[$i], 8), "Address:", ""), "Addresses:", "") If $i < UBound($a_tmp) - 1 Then $s_tmp &= "," Next ; Split the string to an array $a_IPs = StringSplit($s_tmp, ",", 2) ; Return the array Return $a_IPs EndFunc ;==>_LookupIPs ; Function Name _RunReadStd() ; ================================================================================================== ; ; Function Name: _RunReadStd() ; Description:: Run a specified command, and return the Exitcode, StdOut text and ; StdErr text from from it. StdOut and StdErr are @tab delimited, ; with blank lines removed. ; Parameter(s): $doscmd: the actual command to run, same as used with Run command ; $timeoutSeconds: maximum execution time in seconds, optional, default: 0 (wait forever), ; $workingdir: directory in which to execute $doscmd, optional, default: @ScriptDir ; $flag: show/hide flag, optional, default: @SW_HIDE ; $sDelim: stdOut and stdErr output deliminter, optional, default: @TAB ; $nRetVal: return single item from function instead of array, optional, default: -1 (return array) ; Requirement(s): AutoIt 3.2.10.0 ; Return Value(s): An array with three values, Exit Code, StdOut and StdErr ; Author(s): lod3n ; (Thanks to mrRevoked for delimiter choice and non array return selection) ; (Thanks to mHZ for _ProcessOpenHandle() and _ProcessGetExitCode()) ; (MetaThanks to DaveF for posting these DllCalls in Support Forum) ; (MetaThanks to JPM for including CloseHandle as needed) ; ; ================================================================================================== Func _RunReadStd($doscmd, $timeoutSeconds = 0, $workingdir = @ScriptDir, $flag = @SW_HIDE, $nRetVal = -1, $sDelim = @TAB) Local $aReturn, $i_Pid, $h_Process, $i_ExitCode, $sStdOut, $sStdErr, $runTimer Dim $aReturn[3] ; run process with StdErr and StdOut flags $runTimer = TimerInit() $i_Pid = Run($doscmd, $workingdir, $flag, 6) ; 6 = $STDERR_CHILD+$STDOUT_CHILD ; Get process handle Sleep(100) ; or DllCall may fail - experimental $h_Process = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $i_Pid) ; create tab delimited string containing StdOut text from process $aReturn[1] = "" $sStdOut = "" While 1 $sStdOut &= StdoutRead($i_Pid) If @error Then ExitLoop WEnd $sStdOut = StringReplace($sStdOut, @CR, @TAB) $sStdOut = StringReplace($sStdOut, @LF, @TAB) $aStdOut = StringSplit($sStdOut, @TAB, 1) For $i = 1 To $aStdOut[0] $aStdOut[$i] = StringStripWS($aStdOut[$i], 3) If StringLen($aStdOut[$i]) > 0 Then $aReturn[1] &= $aStdOut[$i] & $sDelim EndIf Next $aReturn[1] = StringTrimRight($aReturn[1], 1) ; create tab delimited string containing StdErr text from process $aReturn[2] = "" $sStdErr = "" While 1 $sStdErr &= StderrRead($i_Pid) If @error Then ExitLoop WEnd $sStdErr = StringReplace($sStdErr, @CR, @TAB) $sStdErr = StringReplace($sStdErr, @LF, @TAB) $aStderr = StringSplit($sStdErr, @TAB, 1) For $i = 1 To $aStderr[0] $aStderr[$i] = StringStripWS($aStderr[$i], 3) If StringLen($aStderr[$i]) > 0 Then $aReturn[2] &= $aStderr[$i] & $sDelim EndIf Next $aReturn[2] = StringTrimRight($aReturn[2], 1) ; kill the process if it exceeds $timeoutSeconds If $timeoutSeconds > 0 Then If TimerDiff($runTimer) / 1000 > $timeoutSeconds Then ProcessClose($i_Pid) EndIf EndIf ; fetch exit code and close process handle If IsArray($h_Process) Then Sleep(100) ; or DllCall may fail - experimental $i_ExitCode = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $h_Process[0], 'int*', 0) If IsArray($i_ExitCode) Then $aReturn[0] = $i_ExitCode[2] Else $aReturn[0] = -1 EndIf Sleep(100) ; or DllCall may fail - experimental DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $h_Process[0]) Else $aReturn[0] = -2 EndIf ; return single item if correctly specified with with $nRetVal If $nRetVal <> -1 And $nRetVal >= 0 And $nRetVal <= 2 Then Return $aReturn[$nRetVal] ; return array with exit code, stdout, and stderr Return $aReturn EndFunc ;==>_RunReadStd ; Function Name _MSPing() ; ================================================================================================== Func _MSPing($hostname, $timeout = 50) Local $return_struc[4] ; [0] = Result (in ms) ; [1] = The hostname originally used ; [2] = Process handle (for internal use only) ; [3] = Buffer (for internal use only) $return_struc[1] = $hostname $return_struc[2] = Run("ping " & $hostname & " -n 1 -w " & $timeout, "", @SW_HIDE, $STDOUT_CHILD) Return $return_struc EndFunc ;==>_MSPing ; Function Name _MSPingIsReady() ; ================================================================================================== Func _MSPingIsReady(ByRef $return_struc) Return ___MSPingReadOutput($return_struc) EndFunc ;==>_MSPingIsReady ; Function Name _MSPingGetResult() ; ================================================================================================== Func _MSPingGetResult($return_struc) Return $return_struc[0] EndFunc ;==>_MSPingGetResult ; Function Name _MSPingGetHostname() ; ================================================================================================== Func _MSPingGetHostname($return_struc) Return $return_struc[1] EndFunc ;==>_MSPingGetHostname ; Function Name ___MSPingReadOutput() ; ================================================================================================== ; Internal use only Func ___MSPingReadOutput(ByRef $return_struc) $data = StdoutRead($return_struc[2]) If (@error) Then ___MSPingParseResult($return_struc) Return 1 Else $return_struc[3] &= $data Return 0 EndIf EndFunc ;==>___MSPingReadOutput ; Function Name ___MSPingParseResult() ; ================================================================================================== ; Internal use only Func ___MSPingParseResult(ByRef $return_struc) $result = StringRegExp($return_struc[3], "([0-9]*)ms", 3) If @error Then $return_struc[0] = -1 Else $return_struc[0] = $result[0] EndIf EndFunc ;==>___MSPingParseResult ; Function __ArrayAdd to add lines to a two-dimensional array ; ============================================================================================== Func _2DArrayAdd(ByRef $avArray, $vValue, $NestArray = True) Local $iBoundArray0, $iBoundArray1, $iBoundArray2, $iBoundValue1 ; $avArray is not an array If IsArray($avArray) = 0 Then Return SetError(1, 0, -1) ; No. of dimesions in array $iBoundArray0 = UBound($avArray, 0) ; $avArray is more than 2D If $iBoundArray0 > 2 Then Return SetError(1, 1, -1) ; Size of array in first dimension $iBoundArray1 = UBound($avArray, 1) ; Size of array in second dimension If $iBoundArray0 = 2 Then $iBoundArray2 = UBound($avArray, 2) ; If input array is 1D, or $vValue is not an array, or $NestArray = True (default) then save $vValue literally If ($iBoundArray0 = 1) Or (IsArray($vValue) = 0) Or $NestArray Then If $iBoundArray0 = 1 Then ; Add to 1D array ReDim $avArray[$iBoundArray1 + 1] $avArray[$iBoundArray1] = $vValue Else ; Add to 2D array at [n][0] ReDim $avArray[$iBoundArray1 + 1][$iBoundArray2] $avArray[$iBoundArray1][0] = $vValue EndIf Else ; If input array is 2D, and $vValue is an array, and $NestArray = False, ; then $vValue is a 1D array of values to add as a new row. ; $vValue array is not 1D If UBound($vValue, 0) <> 1 Then Return SetError(1, 2, -1) $iBoundValue1 = UBound($vValue, 1) ; $vValue array has too many elements If $iBoundArray2 < $iBoundValue1 Then Return SetError(1, 3, -1) ReDim $avArray[$iBoundArray1 + 1][$iBoundArray2] For $n = 0 To $iBoundValue1 - 1 $avArray[$iBoundArray1][$n] = $vValue[$n] Next EndIf ; Return index of new last row in $avArray Return $iBoundArray1 EndFunc ;==>_2DArrayAdd So finally I have to say that you, after destroying my holy weekend , made two of my days this week. Thank you very much, you're great, dude!!! Edited October 29, 2009 by cherdeg
llewxam Posted November 15, 2009 Posted November 15, 2009 Awesome script Manadar!! I have a use for something like this for a client whose free IP addresses are few and hard to find, so I put a simple GUI on it: expandcollapse popup#include <Constants.au3> #include <Array.au3> #include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <StaticConstants.au3> $localip=@IPAddress1 $oct=StringSplit($localip,".") $range=$oct[1]&"."&$oct[2]&"."&$oct[3]&"." GUICreate("IP Scanner",300,325,@desktopwidth/2,@desktopheight/4) GUICtrlCreateLabel("Used IP Addresses",15,5,140,20) GUICtrlCreateLabel("Free IP Addresses",165,5,140,20) $used=GUICtrlCreateList("",5,25,140,270) $open=GUICtrlCreateList("",155,25,140,270) $prog=GUICtrlCreateProgress(5,300,290,20) GUISetState(@SW_SHOW,"IP Scanner") Local $done Local Const $MAX_PROCESS = 10 ; We spawn a maximum of 10 processes at once Local $a_process[$MAX_PROCESS] ; An array to keep a reference to spawned processes, in the next loop we fill it with value 0 For $i = 0 to UBound($a_process)-1 $a_process[$i] = 0 Next ; The following array represents a list of hosts, these are probably provided from a file later on Local $address[255] For $i = 0 to 254 $address[$i] = $range & $i+1 ; We generate some IPs Next Local $i = 0 ; A pointer to run through the $address array Local $finished = 0 ; <==== New line While True ; Check on the current processes, and look if there is one finished for use with our next host in line (from $address) For $n = 0 to UBound($a_process)-1 $msg=GUIGetMsg() if $msg=$GUI_EVENT_CLOSE then Exit If ($i <> UBound($address) AND $a_process[$n] == 0) Then ; Check if we need a spot, and there is an existing spot ; There is an empty spot $a_process[$n] = _MSPing($address[$i]) $i += 1 Else ; Something is running here, let's check on the output If ($a_process[$n] <> 0 And _MSPingIsReady($a_process[$n])) Then ; We have an output here, let's get it! GUICtrlSetData($prog,($done/255)*100) $hostname = _MSPingGetHostname($a_process[$n]) $pingtime = _MSPingGetResult($a_process[$n]) If ($pingtime <> -1) Then GUICtrlSetData($used,$hostname) $done+=1 Else GUICtrlSetData($open,$hostname) $done+=1 EndIf ; Free up an empty space for the next address to Ping $a_process[$n] = 0 $finished += 1 ; <=== New line If ($finished == UBound($address)) Then ExitLoop 2 ; Return EndIf EndIf EndIf Next Sleep(50) ; Give existing ping commands some time to process the request WEnd GUICtrlDelete($prog) GUICtrlCreateLabel("Done scanning IP range",5,300,290,20,$SS_CENTER) Do $msg=GUIGetMsg() if $msg=$GUI_EVENT_CLOSE then Exit Until 1=2 Func _MSPing($hostname, $timeout = 50) Local $return_struc[4] ; [0] = Result (in ms) ; [1] = The hostname originally used ; [2] = Process handle (for internal use only) ; [3] = Buffer (for internal use only) $return_struc[1] = $hostname $return_struc[2] = Run("ping " & $hostname & " -n 1 -w " & $timeout, "", @SW_HIDE, $STDOUT_CHILD) Return $return_struc EndFunc Func _MSPingIsReady(ByRef $return_struc) Return ___MSPingReadOutput($return_struc) EndFunc Func _MSPingGetResult($return_struc) Return $return_struc[0] EndFunc Func _MSPingGetHostname($return_struc) Return $return_struc[1] EndFunc ; Internal use only Func ___MSPingReadOutput(ByRef $return_struc) $data = StdoutRead($return_struc[2]) If (@error) Then ___MSPingParseResult($return_struc) Return 1 Else $return_struc[3] &= $data Return 0 EndIf EndFunc ; Internal use only Func ___MSPingParseResult(ByRef $return_struc) $result = StringRegExp($return_struc[3], "([0-9]*)ms", 3) If @error Then $return_struc[0] = -1 Else $return_struc[0] = $result[0] EndIf EndFunc Hopefully this will make a nice addition to a great tool!! Ian My projects: IP Scanner - Multi-threaded ping tool to scan your available networks for used and available IP addresses, shows ping times, resolves IPs in to host names, and allows individual IPs to be pinged. INFSniff - Great technicians tool - a tool which scans DriverPacks archives for INF files and parses out the HWIDs to a database file, and rapidly scans the local machine's HWIDs, searches the database for matches, and installs them. PPK3 (Persistent Process Killer V3) - Another for the techs - suppress running processes that you need to keep away, helpful when fighting spyware/viruses. Sync Tool - Folder sync tool with lots of real time information and several checking methods. USMT Front End - Front End for Microsoft's User State Migration Tool, including all files needed for USMT 3.01 and 4.01, 32 bit and 64 bit versions. Audit Tool - Computer audit tool to gather vital hardware, Windows, and Office information for IT managers and field techs. Capabilities include creating a customized site agent. CSV Viewer - Displays CSV files with automatic column sizing and font selection. Lines can also be copied to the clipboard for data extraction. MyDirStat - Lists number and size of files on a drive or specified path, allows for deletion within the app. 2048 Game - My version of 2048, fun tile game. Juice Lab - Ecigarette liquid making calculator. Data Protector - Secure notes to save sensitive information. VHD Footer - Add a footer to a forensic hard drive image to allow it to be mounted or used as a virtual machine hard drive. Find in File - Searches files containing a specified phrase.
Fr0zT Posted December 14, 2009 Posted December 14, 2009 (edited) Hey Manadar,I've finally got my threaded ping working using ASM and createthread. No need to use stdout anymore...http://www.autoitscript.com/forum/index.php?showtopic=106354&st=0&p=754025&#entry754025Fr0zT Edited December 14, 2009 by Fr0zT [size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size]
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