Jump to content

versatile multi ping


Gianni
 Share

Recommended Posts

I needed a function to ping many computers, and get the results of the pings in an array so to manage it easily in a script.
Searching in the forum I found some interesting sw with a nice graphical interface, but not a generic function that simply return an array.
a very powerful pinger I found is >nPing by Manadar,  but it is designed as a command line tool, so I decided to use the entire engine  of nPing adapting it a bit, so that it can be used as an udf.
This code is a first attempt (beta) and it can be used to:

Ping all computers (IP addresses) belonging to the (local) LAN
just call the _nPing() without any parameter

Ping a predefined list of IP
just pass the list of host (IP or hastnames) to the function in an 1D zero based array or in a 2D array indicating the column containing the addresses

Ping all computers (IP addresses) of a remote LAN
just pass an IP of that lan and his subnet mask

Ping range of computers (IP addresses)
just pass a string rappresenting the range of IP to ping (as accepted by the nPing program by Manadar),
for example:
192.168.0.0-1        will ping these addresses: 192.168.0.0 and 192.168.0.1
192.168.20.*           will ping everything in the range from 192.168.20.1 to 192.168.20.255
192.168.0-1.1-254    will ping everything in the range from 192.168.0.1 to 192.168.1.254

; #FUNCTION# ====================================================================================================================
; Name...........: _nPing
; Description ...: returns an array containing: clients responding to ping or clients not responding or both. See $ReturnFlag
; Syntax.........: _nPing([[$IP]|[$IPArray]|[$IPrange]],[[$NetMask]|[$column]], [$ReturnFlag], [$Resolve], [$MyFunction])
; Parameters ....: [[$IP]|[$IPArray]|[$IPrange]] - An IP address or an 1D or 2D array (0 based) or an IPrange(*)
;                  $NetMask  - An 4 digit Net Mask or a CIDR notation value (numbers of bit from 1 to 32)
;                              if previous parameter is an 2D array then this parameter contains the
;                              nr. of the column in the passed array that contains the addresses to be pinged
;                  $ReturnFlag - 0|1|2, what to return: 0=all cliensts; 1=responding clients; 2= not responding clients(**)
;                  $Resolve - O or 1, if IP lookup name resolution must be performed; 1 = yes, 0 = no
;                  $MyFunction - an User Defined Function to be called each time a PING complete (default is progress bar)

;                                the called function receives 1 parameter that is an array containing the following 6 parameters:

;                                [0] nr. of total addresses under process
;                                [1] nr. of ping already finished
;                                [2] IP just processed
;                                [3] resolved Host name or -1 if IP is down
;                                [4] roundtrip of this ping or -1 if IP is down
;                                [5] Index of this IP within the caller's passed array
;                                by default is called the _Progress() function that will display the progress bar
; Return values .: Success - an 2D array containing:
;                  first row ($array[0][x]) contains: [0][0]= nr. of returned host; [0][1]= total roundtrip
;                  other rows: [n][0]=Address; [n][1]=lookup name; [n][2]=roundtrip; [n][3]=index in the passed array***
;                  Failure - -1, sets @error
;                  |1 - too many IP, max 16777216 ($MAX_HOSTS)
;                  |2 - wrong array dimensions or wrong column number
;                  |3 - wrong IP
;                  |4 - wrong subnet mask
;                  |5 - bad "range" or wrong IP error
;                  |6 - Windows Sockets Error
;                  |7 - (not used)
;                  |8 - DLL call error (reading local subnet mask)
;
;             (*)  IPrange is a string as below
;                  "192.168.0.0-1"        will ping these addresses: 192.168.0.0 and 192.168.0.1
;                  "192.168.20.*"       will ping everything in the range from 192.168.20.1 to 192.168.20.255
;                  "192.168.0-1.1-254"    will ping everything in the range from 192.168.0.1 to 192.168.1.254
;
;             (**) returnead 2D array has the following 4 columns:
;                  first row contains: [0][0]= nr. of returned host; [0][1]= total roundtrip
;                  following rows contains fields as below
;                  +-------------------------+-------------------------+
;                  | nr of elements in array | total roundtrip         |
;                  +-------------------------+-------------------------+-------------------------+-------------------------+
;                  | IP address              | [hostname] ( -1 )       | roundtrip (or -1)       | index ***               |
;                  +-------------------------+-------------------------+-------------------------+-------------------------+
;
;            (***) since the returned array has not the same nr. of rows and also has not the same order of the array in input,
;                  this index is a reference to "bind" both arrays.
;                  It is more useful if the input array is a 2D array and you have to bind the rows containing results
;                  with related fields (array elements) in the "source" array

I have not done extensive testing on it, so I would be grateful if someone that tries it, can report any error
thanks

EDIT:

After some testing, I have seen that sometime some IP are reported as dead, while are alive instead.
This occurs when a device is not so fast to answer to the ping, and so it's marked as dead while instead is only too slow to answer to the ping.

 I  came to the conclusion that for a more accurate result about the not responding devices, is better to use a $timeout parameter of 4000 ms as default value in the _MSPing() function (the same default timeout value as in the standard ping command)

So I have "calibrated" the multiping.au3 by modifying the line 349 and incrementing the value of the $Timeout variable from 100 ms to 4000 ms.
This should be a better choice  for a general purpose utilization that gives more stable and accurate results about the not responding devices.

This should not slow down the overall performances, but will only give some more time  to respond to the slower devices.

MultiPing.au3

#include <iNet.au3>

; #INDEX# =======================================================================================================================
; Title .........: _nPing
; AutoIt Version :
; Language ......: English
; Description ...: Function to perform multi Ping.
; Author(s) .....: core engine is Manadar's "nping" retrieved at the following post
;                  http://www.autoitscript.com/forum/topic/108060-nping-console-network-pinger-network-sweeper-network-scanner
;                  adapted to this UDF by PincoPanco
; ===============================================================================================================================

; #CURRENT# =====================================================================================================================
; _nPing                    multi IP pinger
; ===============================================================================================================================

; #INTERNAL_USE =================================================================================================================
; _LanParameters            given IP and mask generate [and display] various lan parameters
; _CIDR_To_Mask             transform a CIDR number (1 - 32) to the corresponding 4 digit mask
; _Mask_To_CIDR             transform a 4 digit mask to the corresponding CIDR number (1 - 32)
; _GetSubnetMask            given the local IP returns the related subnet mask (thanks to dragan)
; _Convert_To_Binary        from decimal to binary
; _Bin_To_Dec               from binary to decimal
; _FileReadToArray_mod      read a file of IP in a 1D array, if is a csv and a separator is passed a 2D array is returned
; _GetIpAddressList         Generate the IP list to Ping
; _Make_Range               Given an IP and his mask, this function return the full LAN "range" for _nPing
; _GetLanParameters         calculate all IP/subnet related parameters
; _isIPaddr                 check if passed IP is a plausible IP
; _isSNmask                 check if passed mask is a plausible mask
; _Progress                 shows a progress bar for the current scan
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name...........: _nPing
; Description ...: returns an array containing: clients responding to ping or clients not responding or both. See $ReturnFlag
; Syntax.........: _nPing([[$IP]|[$IPArray]|[$IPrange]],[[$NetMask]|[$column]], [$ReturnFlag], [$Resolve], [$MyFunction])
; Parameters ....: [[$IP]|[$IPArray]|[$IPrange]] - An IP address or an 1D or 2D array (0 based) or an IPrange(*)
;                  $NetMask  - An 4 digit Net Mask or a CIDR notation value (numbers of bit from 1 to 32)
;                              if previous parameter is an 2D array then this parameter contains the
;                              nr. of the column that contains the addresses to be pinged
;                  $ReturnFlag - 0|1|2, what to return: 0=all cliensts; 1=responding clients; 2= not responding clients(**)
;                  $Resolve - O or 1, if IP lookup name resolution must be performed; 1 = yes, 0 = no
;                  $MyFunction - an User Defined Function to be called each time a PING complete (default is progress bar)
;                                the called function receives 1 parameter that is an array containing the following 6 parameters:
;                                [0] nr. of total addresses under process
;                                [1] nr. of ping already finished
;                                [2] IP just processed
;                                [3] resolved Host name or -1 if IP is down
;                                [4] roundtrip of this ping or -1 if IP is down
;                                [5] Index of this IP within the caller's passed array
;                                by default is called the _Progress() function that will display the progress bar
; Return values .: Success - an 2D array containing:
;                  first row ($array[0][x]) contains: [0][0]= nr. of returned host; [0][1]= total roundtrip
;                  other rows: [n][0]=Address; [n][1]=lookup name; [n][2]=roundtrip; [n][3]=index in the passed array***
;                  Failure - -1, sets @error
;                  |1 - too many IP, max 16777216 ($MAX_HOSTS)
;                  |2 - wrong array dimensions or wrong column number
;                  |3 - wrong IP
;                  |4 - wrong subnet mask
;                  |5 - bad "range" or wrong IP error
;                  |6 - Windows Sockets Error
;                  |7 - (not used)
;                  |8 - DLL call error (reading local subnet mask)
;
;             (*)  IPrange is a string as below
;                  "192.168.0.0-1"      will ping these addresses: 192.168.0.0 and 192.168.0.1
;                  "192.168.20.*"       will ping everything in the range from 192.168.20.1 to 192.168.20.255
;                  "192.168.0-1.1-254"  will ping everything in the range from 192.168.0.1 to 192.168.1.254
;
;             (**) returnead 2D array has the following 4 columns:
;                  first row contains: [0][0]= nr. of returned host; [0][1]= total roundtrip
;                  following rows contains fields as below
;                  +-------------------------+-------------------------+
;                  | nr of elements in array | total roundtrip         |
;                  +-------------------------+-------------------------+-------------------------+-------------------------+
;                  | IP address              | [hostname] ( -1)        | roundtrip (or -1)       | index ***               |
;                  +-------------------------+-------------------------+-------------------------+-------------------------+
;
;            (***) since the returned array has not the same nr. of rows and also has not the same order of the array in input,
;                  this index is a reference to "bind" both arrays.
;                  It is more useful if the input array is a 2D array and you have to bind the rows containing results
;                  with related fields (array elements) in the "source" array

; Author ........:
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================

Func _nPing($networkRange = "", $MyMask = "", $ReturnFlag = 1, $Resolve = 0, $MyFunction = "_Progress")

    Static $TCP = TCPStartup() ; this should be used at the beginning of the main program instead of inside the Func()
    Static $dig = FileExists(".\dig\dig.exe") ; this is for IP to hostname resolution. if dig.exe exists will be used. (faster than _TCPIpToName)

    Local $MAX_PROCESS = 20 ; A maximum number of processes (25)
    ; Global $MAX_HOSTS = 16777216 ; A maximum number of hosts to ping due to AutoIt's array limit size
    Local $_IPup[1][4] ; will contain results of PINGs [IP][roundrip or -1]

    ;   check what has been required from caller
    If $networkRange = "" Then ; no parameters passed, so scan local network
        ; ConsoleWrite("debug: no IP/range provided, I will scan the local LAN" & @CRLF)
        $networkRange = _Make_Range(TCPNameToIP(@ComputerName), _GetSubnetMask(TCPNameToIP(@ComputerName))) ; retrieve local LAN and Subnet Mask values
        If @error Then Return SetError(@error, @extended, -1)
        ; ConsoleWrite("debug: network range=" & $networkRange & @CRLF)

    ElseIf IsArray($networkRange) Then ; ----- is an array -----------------------------+
        ; if is an 2D array then $MyMask contains the column else is ignored            |
        If UBound($networkRange) > 16777216 Then Return SetError(1, 0, -1) ;            | too many IP > $MAX_HOSTS
        ; If UBound($networkRange, 0) <> 1 Then Return SetError(2, 0, -1) ;             |
        If UBound($networkRange, 0) > 2 Then Return SetError(2, 0, -1) ;                | max 2D array
        If UBound($networkRange, 0) = 1 Then ;                                          |
            $aArray = $networkRange ;   $aArray = all IP to scan                        |
        Else ;                ----- it is a 2D array -----                              |
            ; the number of the column with addresses is in $MyMask parameter           |
            If $MyMask > UBound($networkRange, 2) - 1 Then Return SetError(2, 0, -1) ;  | wrong column
            Local $aArray[UBound($networkRange)] ;                                      |
            For $i = 0 To UBound($networkRange) - 1 ;                                   |
                $aArray[$i] = $networkRange[$i][$MyMask] ;                              |
            Next ;                                                                      |
        EndIf ;                                                                         |
        ; ------------------------------------------------------------------------------+

    ElseIf _isIPaddr($networkRange) Then ; single IP
        ; ConsoleWrite("debug: single IP value received" & @CRLF)
        If $MyMask <> "" Then ; is there a subnet?
            If Not _isSNmask($MyMask) Then ; wrong 4 digit mask
                If $MyMask > 0 And $MyMask < 33 Then ; is it a CIDR notation number? (nr. of bits of mask (1 to 32))
                    $MyMask = _CIDR_To_Mask($MyMask)
                Else
                    Return SetError(4, 0, -1) ; wrong mask provided
                EndIf
            EndIf
            $networkRange = _Make_Range($networkRange, $MyMask) ; generate the "range" of all IP belonging to that subnet mask
        EndIf
    EndIf

    If Not IsArray($networkRange) Then
        ; ConsoleWrite("debug: Is not an Array" & @CRLF)
        ; if $networkRange is NOT an array then it is a "range"
        ; either passed as parameter by caller or generated by above checks
        $aArray = _GetIpAddressList($networkRange) ; Generate the list of IP to be pinged
        If @error Then Return SetError(5, 0, -1) ; IP range error
    EndIf
    ;
    ;   _ArrayDisplay($aArray,"debug") ; $aArray should contain the IP to be pinged by _nPing
    ;
    ;   ***********************************************************************************************************
    ;   here start of nping core by Manadar (slightly modified)
    ;   http://www.autoitscript.com/forum/topic/108060-nping-console-network-pinger-network-sweeper-network-scanner
    ;   ***********************************************************************************************************

    If $ReturnFlag = 0 Then ; make room for all clients
        ReDim $_IPup[UBound($aArray) + 1][4] ; $_IPup will contain results
    EndIf

    Local $aProcess[$MAX_PROCESS] ; An array to keep a reference to spawned processes, in the next loop we fill it with value 0 for reference
    For $i = 0 To UBound($aProcess) - 1
        $aProcess[$i] = 0
    Next

    Local $i = 0 ; which IP are we currently trying to ping ( based on array )
    Local $iFinished = 0 ; how many processes have finished pinging
    Local $iUp = 0 ; Total hosts that are UP
    Local $iDown = 0 ; Total hosts that are DOWN
    Local $iTotalRoundTrip = 0 ; Total roundtrip (all the +ms added together)
    While 1
        ; We check all the currently running processes
        For $n = 0 To UBound($aProcess) - 1
            ; Check if we need a spot, and there is an existing spot here
            If ($i <> UBound($aArray) And $aProcess[$n] == 0) Then
                $aProcess[$n] = _MSPing($i, $aArray[$i]) ; Start a new Ping process
                $i += 1 ; Increment $i so we can do the next process the next time around
            Else
                ; Check if this process has been spawned and the process is ready
                If ($aProcess[$n] <> 0 And _MSPingIsReady($aProcess[$n])) Then ; has finished to ping
                    ; results of endings pings. (Get results from the various Pimg commands)
                    $sHostname = _MSPingGetHostname($aProcess[$n])
                    $sResult = _MSPingGetResult($aProcess[$n])
                    $sIndex = ___MSPingGetIndex($aProcess[$n]) ; new, added by me (zero based)
                    ; ConsoleWrite("debug: " & $sIndex & " : " & $sHostname & " : " & $sResult & @CRLF)
                    ; --------------------------------------------------------------------------------------------------------------------------------------------------------------
                    If ($sResult <> -1) Then ; current IP is UP
                        ; ConsoleWrite("debug: " & $sHostname & " has a roundtrip of " & $sResult & " ms" & @CRLF)
                        $iUp += 1
                        If $ReturnFlag < 2 Then ; if return all(0) or responding only(1)

                            If $ReturnFlag = 1 Then ; 1 = return back only responding IP
                                ReDim $_IPup[$iUp + 1][4]
                                $_IPup[$iUp][3] = $sIndex ; the index of the passed array that contains this IP
                                $sIndex = $iUp
                            Else ; $ReturnFlag = 0 Then keep all clients
                                $sIndex += 1
                                $_IPup[$sIndex][3] = $sIndex - 1
                            EndIf

                            $_IPup[$sIndex][0] = $sHostname
                            If $Resolve Then ; ------------ resolve IP to hostname ------------
                                If _isIPaddr($_IPup[$sIndex][0]) Then ; is it an IP ? (or an hostname)
                                    If $dig Then ; resolve with dig if is present (much faster especially on passive devices without a host name)
                                        Local $digID = Run(".\dig\dig.exe -x " & $_IPup[$sIndex][0] & " +short", "", @SW_HIDE, 0x2)
                                        Do
                                            $_IPup[$sIndex][1] &= StdoutRead($digID) ; resolved IP to name (if resolvable else empty)
                                        Until @error
                                    Else
                                        ; _TCPIpToName is very slow to return if the remote IP do not belongs to a windows client (example a printer or a router)
                                        $_IPup[$sIndex][1] = _TCPIpToName($_IPup[$sIndex][0])
                                    EndIf
                                Else
                                    $_IPup[$sIndex][1] = $_IPup[$sIndex][0]
                                EndIf
                            EndIf ; End of name resolution -------------------------------------
                            $_IPup[$sIndex][2] = $sResult ; roundtrip of the ping
                            $iTotalRoundTrip += $sResult
                        EndIf
                    Else ; current IP is down ----------------------------------------------------------------------------------------------------------------------------------------
                        $iDown += 1
                        If $ReturnFlag = 0 Then ; 0 return back all IP, responding and not responding
                            $sIndex += 1
                            $_IPup[$sIndex][0] = $sHostname
                            $_IPup[$sIndex][1] = -1 ; loockup name
                            $_IPup[$sIndex][2] = -1 ; roundtrip
                            $_IPup[$sIndex][3] = $sIndex - 1
                            ;   ElseIf $ReturnFlag = 1 Then ; $ReturnFlag = 1 return only responding
                            ;   nothing to store
                        ElseIf $ReturnFlag = 2 Then ; $ReturnFlag = 2 return only not responding
                            ReDim $_IPup[$iDown + 1][4]
                            $_IPup[$iDown][0] = $sHostname
                            $_IPup[$iDown][1] = -1
                            $_IPup[$iDown][2] = -1
                            $_IPup[$iDown][3] = $sIndex
                            $sIndex = $iDown
                        EndIf
                    EndIf
                    ; ***************************************************
                    ; Free up an empty space for the next address to Ping
                    $aProcess[$n] = 0
                    ; Increment the total of processes that have finished
                    $iFinished += 1

                    If ($sResult <> -1 And $ReturnFlag <> 2) Or ($sResult = -1 And $ReturnFlag <> 1) Then
                        ; call an UDF to track and manage what's going on during the scan;
                        ; an array is passed to the called function with the following 6 parameters:
                        ; 0) nr. of total addresses under process
                        ; 1) nr. of ping already finished
                        ; 2) IP just processed
                        ; 3) resolved Host name or -1 if IP is down
                        ; 4) roundtrip of this ping or -1 if IP is down
                        ; 5) Index of this IP within the caller's passed array
                        ; by default is called the _Progress() function that will display the progress bar
                        Local $aPass_Args[6] = [UBound($aArray), $iFinished, $_IPup[$sIndex][0], $_IPup[$sIndex][1], $_IPup[$sIndex][2], $_IPup[$sIndex][3]]
                        Local $aArgs[2] = ["CallArgArray", $aPass_Args]
                        Call($MyFunction, $aArgs)
                    Else
                        Local $aPass_Args[6] = [UBound($aArray), $iFinished, $sHostname, -1, -1, $sIndex]
                        Local $aArgs[2] = ["CallArgArray", $aPass_Args]
                        Call($MyFunction, $aArgs)
                    EndIf

                    ; If the total number of finished processes
                    If ($iFinished == UBound($aArray)) Then ExitLoop 2 ;  Exit -----+
                EndIf ;                                                             |
            EndIf ;                                                                 |
        Next ;                                                                      |
        Sleep(50) ; Give existing ping commands some time to process the request    |
    WEnd ;                                                                          |
    ;                                                           <-------------------+
    ;  fill record [0]
    If $ReturnFlag = 0 Then ; return all
        $_IPup[0][0] = $iUp + $iDown
        $_IPup[0][1] = $iUp ; $iTotalRoundTrip
        ;   $_IPup[0][2] = $iDown
    ElseIf $ReturnFlag = 1 Then ; return only up
        $_IPup[0][0] = $iUp
        $_IPup[0][1] = $iTotalRoundTrip
        ;   $_IPup[0][2] = $iDown
    ElseIf $ReturnFlag = 2 Then ; return only down
        $_IPup[0][0] = $iDown
        $_IPup[0][1] = -1
        ;   $_IPup[0][2] = $iUp
    EndIf
    Return $_IPup ; - - - The end of scan - - -
EndFunc   ;==>_nPing

Func _GetIpAddressList($ipFormat) ; Generate the IP list to Ping
    If $ipFormat = "" Then
        Return SetError(5, 0, -1) ; no IP to ping
    EndIf

    $ipFormat = StringReplace($ipFormat, "*", "1-255") ; change * with  "1-255"
    $ipSplit = StringSplit($ipFormat, ".")

    If $ipSplit[0] <> 4 Then ; if it is not an IP address then check if it is an hostname
        Static $TCP = TCPStartup()
        Local $ret[1] = [TCPNameToIP($ipFormat)] ; from hostname to IP
        If @error Then Return SetError(6, @error, -1) ; windows API WSAGetError Windows Sockets Error in @extended
        Return $ret ; -----> return
    EndIf

    For $i = 1 To 4 ; controls once again
        If Not StringRegExp($ipSplit[$i], "[0-9\-]*") Then ; are 4 octets numbers
            Static $TCP = TCPStartup()
            Local $ret[1] = [TCPNameToIP($ipFormat)] ; if not number try to decode from host to IP
            If @error Then Return SetError(6, @error, -1) ; windows API WSAGetError. Windows Sockets Error in @extended
            Return $ret ; -----> return
        EndIf
    Next
    ;   $ipFormat is not an hostname
    Local $ipRange[4][2], $totalPermu = 1

    For $i = 0 To 3
        If StringInStr($ipSplit[$i + 1], "-") Then ; control the presence of the "-" sign
            $m = StringSplit($ipSplit[$i + 1], "-")
            $ipRange[$i][0] = $m[1]
            $ipRange[$i][1] = $m[2]
        Else
            $n = Number($ipSplit[$i + 1])
            $ipRange[$i][0] = $n
            $ipRange[$i][1] = $n
        EndIf
        $totalPermu *= $ipRange[$i][1] - $ipRange[$i][0] + 1 ; total number of IP to check
        If ($ipRange[$i][0] < 0 Or $ipRange[$i][0] > 255) Or ($ipRange[$i][1] < 0 Or $ipRange[$i][1] > 255) Then Return SetError(3, 0, -1) ; wrong IP
    Next
    If $totalPermu > 16777216 Then ; > $MAX_HOSTS
        Return SetError(1, String($totalPermu), -1) ; too many IP
    EndIf

    Local $result[$totalPermu], $i = 0

    For $a = $ipRange[0][0] To $ipRange[0][1]
        For $b = $ipRange[1][0] To $ipRange[1][1]
            For $c = $ipRange[2][0] To $ipRange[2][1]
                For $d = $ipRange[3][0] To $ipRange[3][1]
                    $result[$i] = $a & "." & $b & "." & $c & "." & $d ; $result contains the IP addresses to ping
                    $i += 1
                Next
            Next
        Next
    Next

    Return $result
EndFunc   ;==>_GetIpAddressList

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Func _MSPing($Array_ndx, $sHostname, $timeout = 4000) ;$timeout = 50) ; start a new Ping
    Local $return_struc[5]
    ; [0] = Result (in ms)
    ; [1] = The hostname originally used
    ; [2] = Process handle (for internal use only)
    ; [3] = Buffer (for internal use only)
    ; [4] = Index of IP in source array **new**

    $return_struc[1] = $sHostname
    $return_struc[2] = Run("ping " & $sHostname & " -n 1 -w " & $timeout, "", @SW_HIDE, 0x2) ; 0x2 -> $STDOUT_CHILD)
    $return_struc[4] = $Array_ndx

    Return $return_struc
EndFunc   ;==>_MSPing

Func _MSPingIsReady(ByRef $return_struc) ; check if Ping has finished
    Return ___MSPingReadOutput($return_struc)
EndFunc   ;==>_MSPingIsReady

Func _MSPingGetResult($return_struc)
    Return $return_struc[0]; [0] = Result (in ms)
EndFunc   ;==>_MSPingGetResult

Func _MSPingGetHostname($return_struc) ; returns the hostname
    Return $return_struc[1]; [1] = The hostname originally used
EndFunc   ;==>_MSPingGetHostname

; Internal use only
Func ___MSPingReadOutput(ByRef $return_struc) ; peek result of DOS Ping command
    $data = StdoutRead($return_struc[2]) ; [2] = Process handle (for internal use only)
    If (@error) Then ; if ping has finished
        ___MSPingParseResult($return_struc) ; extract time taken by ping
        Return 1 ; 1 = finished
    Else
        $return_struc[3] &= $data ; [3] = Buffer (for internal use only) ; contains DOS output
        Return 0 ; 0 = not yet finished
    EndIf
EndFunc   ;==>___MSPingReadOutput

; Internal use only
Func ___MSPingParseResult(ByRef $return_struc) ; extract from Ping command the millisecond value
    $result = StringRegExp($return_struc[3], "([0-9]*)ms", 3); [3] = DOS command output is here
    If @error Then
        $return_struc[0] = -1 ; [0] = Result (in ms) -1 if error
    Else
        $return_struc[0] = $result[0] ; returns the first millisecond value retrieved from Ping
    EndIf
EndFunc   ;==>___MSPingParseResult

; Internal use only - new (added by me)
Func ___MSPingGetIndex(ByRef $return_struc) ; Index of the current IP in passed array
    Return $return_struc[4]
EndFunc   ;==>___MSPingGetIndex

; = = = = = net related functions = = = = =

Func _Make_Range($ipLan, $sMask) ; Given an IP and his mask, this function return the full LAN "range" for _nPing
    Local $aLan = _GetLanParameters($ipLan, $sMask)
    If @error Then Return SetError(@error, @extended, -1)
    Return $aLan[7][0]
EndFunc   ;==>_Make_Range

Func _GetLanParameters($theIP1, $sSubNet)
    ; ------------------------------------------
    ; calculate all IP/subnet related parameters
    ; ------------------------------------------
    If Not _isIPaddr($theIP1) Then Return SetError(3, 0, -1) ; wrong IP address
    ;check on subnet
    If Not _isSNmask($sSubNet) Then ; it is not a valid 4 digit subnet
        If $sSubNet > 0 And $sSubNet < 33 Then ; is it a CIDR notation number? nr. of bits 1 to 32
            $sSubNet = _CIDR_To_Mask($sSubNet)
        Else
            Return SetError(4, 0, -1) ; wrong Mask provided
        EndIf
    EndIf

    Local $aLan[8][5] ; net parameters container
    Local $sDot[2] = ['', '.'] ; used as IP octets separator
    Local $aIP = StringSplit($theIP1, '.'), $aSubNet = StringSplit($sSubNet, '.')
    ; split IP address in single octets and calculate related parameters
    For $i = 1 To 4
        $aLan[0][$i] = $aIP[$i] ;                           IP
        $aLan[1][$i] = $aSubNet[$i] ;                       NetMask
        $aLan[2][$i] = BitNOT($aLan[1][$i] - 256) ;         Wildcard, is the inverse of subnet: BitNot($NetMask - 256)
        $aLan[3][$i] = BitAND($aLan[0][$i], $aLan[1][$i]) ; LanAddress  BitAnd(IP, netmask)
        $aLan[4][$i] = BitOR($aLan[0][$i], $aLan[2][$i]) ;  Broadcast address
        $aLan[5][$i] = $aLan[3][$i] ;                       preset First host ; will be $NetAddress + 1
        $aLan[6][$i] = $aLan[4][$i] ;                       preset Last host  ; will be $Broadcast  -1
    Next
    If $sSubNet <> "255.255.255.255" Then
        $aLan[5][4] = BitOR($aLan[5][4], 1) ;                   First host $NetAddress + 1 (Turn last bit ON)
        $aLan[6][4] = BitAND($aLan[6][4], 254) ;                Last host $Broadcast  -1 (Turn last bit OFF)
    EndIf

    For $i = 1 To 4
        $aLan[0][0] &= $aLan[0][$i] & $sDot[$i < 4] ; [0] IP
        $aLan[1][0] &= $aLan[1][$i] & $sDot[$i < 4] ; [1] NetMask
        $aLan[2][0] &= $aLan[2][$i] & $sDot[$i < 4] ; [2] Wildcard
        $aLan[3][0] &= $aLan[3][$i] & $sDot[$i < 4] ; [3] Network
        $aLan[4][0] &= $aLan[4][$i] & $sDot[$i < 4] ; [4] Broadcast
        $aLan[5][0] &= $aLan[5][$i] & $sDot[$i < 4] ; [5] First host
        $aLan[6][0] &= $aLan[6][$i] & $sDot[$i < 4] ; [6] Last host
        ;                                             [7][0] Range for _nPing
        If $aLan[5][$i] = $aLan[6][$i] Then
            $aLan[7][0] &= $aLan[5][$i] & $sDot[$i < 4]
        Else
            $aLan[7][0] &= $aLan[5][$i] & "-" & $aLan[6][$i] & $sDot[$i < 4]
        EndIf
    Next
    ; MsgBox(0, "net", "IP address: " & @TAB & $aLan[0][0] & @CRLF & "Subnet:      " & @TAB & $aLan[1][0] & @CRLF & "Wildcard:   " & @TAB & $aLan[2][0] & @CRLF & "Network:   " & @TAB & $aLan[3][0] & @CRLF & "Broadcast: " & @TAB & $aLan[4][0] & @CRLF & "First host:   " & @TAB & $aLan[5][0] & @CRLF & "Last host:   " & @TAB & $aLan[6][0])
    ; _ArrayDisplay($aLan, "IP/subnet related parameters")
    Return $aLan
EndFunc   ;==>_GetLanParameters
; #FUNCTION# ====================================================================================================================
; Name...........: _LanParameters
; Description ...: given an IP and his subnet returns [and  displays] the following values in dec and binary format:
;                  |IP Address
;                  |Netmask
;                  |Wildcard
;                  |Network Address
;                  |Broadcast Address
;                  |First host
;                  |Last host
; Syntax.........: _LanParameters([$IP, $Subnet])
; Parameters ....:
;
; Return values .:
; Author ........:
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================

Func _LanParameters($theIP1 = "", $sSubNet = "255.255.255.255", $Msg = 0)
    Static $TCP = TCPStartup()
    If $theIP1 = "" Then
        $theIP1 = TCPNameToIP(@ComputerName)
        $sSubNet = _GetSubnetMask($theIP1)
    ElseIf $sSubNet = "" Then
        $sSubNet = "255.255.255.255"
    EndIf
    If Not _isSNmask($sSubNet) Then ; it is not a 4 digit subnet
        If $sSubNet > 0 And $sSubNet < 33 Then ; is it a CIDR notation number? nr. of bits 1 to 32
            $sSubNet = _CIDR_To_Mask($sSubNet)
        Else
            Return SetError(4, 0, False) ; wrong mask
        EndIf
    EndIf

    Local $aLan = _GetLanParameters($theIP1, $sSubNet)
    Local $LanID[7][3]
    $LanID[0][0] = "IP Address       "
    $LanID[1][0] = "Netmask  "
    $LanID[2][0] = "Wildcard         "
    $LanID[3][0] = "Network Address  "
    $LanID[4][0] = "Broadcast Address"
    $LanID[5][0] = "First host       "
    $LanID[6][0] = "Last host        "
    For $i = 0 To 6
        $LanID[$i][1] = $aLan[$i][0]
        $LanID[$i][2] = _Convert_To_Binary($aLan[$i][1]) & "." & _Convert_To_Binary($aLan[$i][2]) & "." & _Convert_To_Binary($aLan[$i][3]) & "." & _Convert_To_Binary($aLan[$i][4])
    Next
    If $Msg Then MsgBox(0, "Lan IDs", $LanID[0][0] & @TAB & $LanID[0][2] & @TAB & $LanID[0][1] & @CRLF & _
            $LanID[1][0] & "( " & _Mask_To_CIDR($LanID[1][1]) & " ) " & @TAB & $LanID[1][2] & @TAB & $LanID[1][1] & @CRLF & _
            $LanID[2][0] & @TAB & $LanID[2][2] & @TAB & $LanID[2][1] & @CRLF & _
            $LanID[3][0] & @TAB & $LanID[3][2] & @TAB & $LanID[3][1] & @CRLF & _
            $LanID[4][0] & @TAB & $LanID[4][2] & @TAB & $LanID[4][1] & @CRLF & _
            $LanID[5][0] & @TAB & $LanID[5][2] & @TAB & $LanID[5][1] & @CRLF & _
            $LanID[6][0] & @TAB & $LanID[6][2] & @TAB & $LanID[6][1] & @CRLF)
    Return $LanID
EndFunc   ;==>_LanParameters

; #FUNCTION# ====================================================================================================================
; Name...........: _CIDR_To_Mask
; Description ...: transform a CIDR number (1 - 32) to the corresponding 4 digit mask
; Syntax.........: _CIDR_To_Mask($CIDR)
; Parameters ....: $CIDR a number from 1 to 32
; Return values .: a 4 bite corresponding subnet mask
; ===============================================================================================================================

Func _CIDR_To_Mask($sSubNet) ; From nr. of bit to 4 digit mask
    $sSubNet = StringLeft(StringLeft("11111111111111111111111111111111", $sSubNet) & "0000000000000000000000000000000", 32)
    $sSubNet = _Bin_To_Dec(StringLeft($sSubNet, 8)) & "." & _Bin_To_Dec(StringMid($sSubNet, 9, 8)) & "." & _Bin_To_Dec(StringMid($sSubNet, 17, 8)) & "." & _Bin_To_Dec(StringRight($sSubNet, 8))
    Return $sSubNet
EndFunc   ;==>_CIDR_To_Mask

; #FUNCTION# ====================================================================================================================
; Name...........: _Mask_To_CIDR
; Description ...: transform a 4 digit mask to the corresponding CIDR number (1 - 32)
; Syntax.........: _Mask_To_CIDR($SubnetMask)
; Parameters ....: $SubnetMask a 4 bite subnet mask
; Return values .: the corresponding CIDR
; ===============================================================================================================================

Func _Mask_To_CIDR($sSubNet) ; from 4 digit mask to nr. of bits
    If _isSNmask($sSubNet) Then
        Local $Digit = StringSplit($sSubNet, ".", 2)
        Return StringInStr(_Convert_To_Binary($Digit[0]) & _Convert_To_Binary($Digit[1]) & _Convert_To_Binary($Digit[2]) & _Convert_To_Binary($Digit[3]), "1", 0, -1)
    Else
        Return SetError(4, 0, False) ; wrong mask
    EndIf
EndFunc   ;==>_Mask_To_CIDR

; _GetSubnetMask
; #FUNCTION# ====================================================================================================================
; Name...........: _GetSubnetMask
; Description ...: given the local IP returns the related subnet mask (thanks to dragan)
;                  http://www.autoitscript.com/forum/topic/155078-how-to-easily-get-the-subnet-mask/?p=1120929
; Syntax.........: _GetSubnetMask($LocalIP)
; Parameters ....: $LocalIP IP of the local computer
; Return values .: the corresponding subnet mask
; ===============================================================================================================================

Func _GetSubnetMask($theIP) ; given the local IP returns the related subnet mask
    Local Const $tagIP_ADDRESS_STRING = "char IPAddress[16];"
    Local Const $tagIP_MASK_STRING = "char IPMask[16];"
    Local Const $tagIP_ADDR_STRING = "ptr Next;" & $tagIP_ADDRESS_STRING & $tagIP_MASK_STRING & "DWORD Context;"
    Local Const $tagIP_ADAPTER_INFO = "ptr Next; DWORD ComboIndex; char AdapterName[260];char Description[132]; UINT AddressLength; BYTE Address[8]; dword Index; UINT Type;" & _
            " UINT DhcpEnabled; ptr CurrentIpAddress; ptr IpAddressListNext; char IpAddressListADDRESS[16]; char IpAddressListMASK[16]; DWORD IpAddressListContext; " & _
            "ptr GatewayListNext; char GatewayListADDRESS[16]; char GatewayListMASK[16]; DWORD GatewayListContext; " & _
            "ptr DhcpServerNext; char DhcpServerADDRESS[16]; char DhcpServerMASK[16]; DWORD DhcpServerContext; " & _
            "int HaveWins; " & _
            "ptr PrimaryWinsServerNext; char PrimaryWinsServerADDRESS[16]; char PrimaryWinsServerMASK[16]; DWORD PrimaryWinsServerContext; " & _
            "ptr SecondaryWinsServerNext; char SecondaryWinsServerADDRESS[16]; char SecondaryWinsServerMASK[16]; DWORD SecondaryWinsServerContext; " & _
            "DWORD LeaseObtained; DWORD LeaseExpires;"
    Local $dll = DllOpen("Iphlpapi.dll")
    If @error Then Return SetError(8, @error, 0); <----------- error  'dll open: Iphlpapi.dll'
    Local $ret = DllCall($dll, "dword", "GetAdaptersInfo", "ptr", 0, "dword*", 0)
    If @error Then
        DllClose($dll)
        Return SetError(8, @error, 0); <----------- error  'dll call function: GetAdaptersInfo'
    EndIf
    Local $adapterBuffer = DllStructCreate("byte[" & $ret[2] & "]")
    Local $adapterBuffer_pointer = DllStructGetPtr($adapterBuffer)
    DllCall($dll, "dword", "GetAdaptersInfo", "ptr", $adapterBuffer_pointer, "dword*", $ret[2])
    If @error Then
        $adapterBuffer = ""
        $adapterBuffer_pointer = ""
        DllClose($dll)
        Return SetError(8, @error, 0); <----------- error 'dll call function: GetAdaptersInfo with adapter buffer pointer'
    EndIf
    Local $adapter = DllStructCreate($tagIP_ADAPTER_INFO, $adapterBuffer_pointer)
    Local $IPType = -1
    Local $FoundIt = False
    Local $retVal = ""
    Do ; -------------------- IP search --------------------
        $Ptr = DllStructGetPtr($adapter, "IpAddressListNext")
        Local $IPStruct, $Index = 0
        Local $allArray[1][3]
        Do
            ReDim $allArray[$Index + 1][3]
            $IPStruct = DllStructCreate($tagIP_ADDR_STRING, $Ptr)
            $allArray[$Index][0] = DllStructGetData($IPStruct, "IPAddress")
            $allArray[$Index][1] = DllStructGetData($IPStruct, "IPMask")
            $allArray[$Index][2] = DllStructGetData($IPStruct, "Context")
            $Ptr = DllStructGetData($IPStruct, "Next")
            $Index += 1
        Until $Ptr = 0
        For $i = 0 To UBound($allArray) - 1
            If $allArray[$i][0] <> $theIP Then ContinueLoop ; >-+
            $retVal = $allArray[$i][1] ;                        |
            $IPType = 0 ;                                       |
            $FoundIt = True ;                                   |
            ExitLoop ; if found do not search over              |
        Next ;                                          <-------+
        If $FoundIt Then ExitLoop ; >---------------------------+
        $Ptr = DllStructGetData($adapter, "Next") ;             |
        $adapter = DllStructCreate($tagIP_ADAPTER_INFO, $Ptr);  |
    Until @error ;                                              |
    ;                               <---------------------------+
    $adapterBuffer = ""
    $adapterBuffer_pointer = ""
    DllClose($dll)
    If Not $FoundIt Then Return SetError(3, 0, 0) ; IP not found <----------- error
    Return SetError(0, $IPType, $retVal) ; OK Return mask
EndFunc   ;==>_GetSubnetMask

Func _isIPaddr($sIPAddr) ; returns true if argument is a plausible IP address
    If Not StringRegExp($sIPAddr, "^((25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(25[0-5]|2[0-4]\d|[01]?\d?\d)$") Then Return SetError(1, 0, False)
    Return True
EndFunc   ;==>_isIPaddr

Func _isSNmask($sSNmask) ; returns true if argument is a correct 4 digit network mask
    If Not StringRegExp($sSNmask, "^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$") Then Return SetError(1, 0, False)
    Return True
EndFunc   ;==>_isSNmask

Func _Progress($aArgs)
    ; Func _Progress($ToDo, $Done, $Dummy1, $Dummy2, $Dummy3, $Dummy4)
    ; this will show the progress bar while scanning
    ; $_Percent = Int($Done / $ToDo * 100)
    $_Percent = Int($aArgs[1] / $aArgs[0] * 100)
    Static $_Progress = 0
    If Not $_Progress Then
        ProgressOn("Progress Meter", "Pinged address ", $aArgs[1] & "/" & $aArgs[0] & " ( 0 %)", -1, -1, 16)
        $_Progress = 1
    EndIf

    ProgressSet($_Percent, $aArgs[1] & "/" & $aArgs[0] & " ( " & $_Percent & " %)", "Pinged address " & $aArgs[2])

    If $_Percent = 100 Then
        ProgressSet(100, "Done", "Complete")
        Sleep(500)
        ProgressOff()
        $_Progress = 0
    EndIf
EndFunc   ;==>_Progress

Func _Convert_To_Binary($iNumber) ; from decimal to binary
    ; http://www.autoitscript.com/forum/topic/90056-decimal-to-binary-number-converter/?p=647505
    Local $sBinString = ""
    While $iNumber
        $sBinString = BitAND($iNumber, 1) & $sBinString
        $iNumber = BitShift($iNumber, 1)
    WEnd
    ; limit returned value to 8 bit 0 - 255
    Return StringRight("00000000" & $sBinString, 8)
EndFunc   ;==>_Convert_To_Binary

Func _Bin_To_Dec($BinNum) ; from binary to decimal
    Local $dec = 0
    For $i = 0 To StringLen($BinNum) - 1
        $dec += 2 ^ $i * StringMid($BinNum, StringLen($BinNum) - $i, 1)
    Next
    Return $dec
EndFunc   ;==>_Bin_To_Dec

; #FUNCTION# ====================================================================================================================
; Name...........: _FileReadToArray_mod
; Description ...: read a file to an array and if is passed a separator and a column number extract only that column (from a csv)
; Syntax.........: _FileReadToArray_mod($sFilePath, $delim = ";")
; Parameters ....: |$sFilePath  -   path and filename of the file to read
;                  |$delim      -   the character separator of the values in the csv
; Remarks .......: if the file is not a csv and contains only one IP per line then $delim is ignored
; Return values .: an 1D array containing the "IP" extracted from the $col column. First column is nr.0
; ===============================================================================================================================
; Func _FileReadColumnToArray($sFilePath, $delim = ";", $col = 0)
Func _FileReadToArray_mod($sFilePath, $delim = ";")
    ; this function is extracted, adapted and slightly modified from the _FileReadToArray() function in file.au3
    Local $aArray
    Local $hFile = FileOpen($sFilePath, 0); $FO_READ)
    If $hFile = -1 Then Return SetError(1, 0, 0);; unable to open the file
    ;; Read the file and remove any trailing white spaces
    Local $aFile = FileRead($hFile, FileGetSize($sFilePath))
    FileClose($hFile)
;~  $aFile = StringStripWS($aFile, 2)
    ; remove last line separator if any at the end of the file
    If StringRight($aFile, 1) = @LF Then $aFile = StringTrimRight($aFile, 1)
    If StringRight($aFile, 1) = @CR Then $aFile = StringTrimRight($aFile, 1)
    If StringInStr($aFile, @LF) Then
        $aArray = StringSplit(StringStripCR($aFile), @LF)
    ElseIf StringInStr($aFile, @CR) Then ;; @LF does not exist so split on the @CR
        $aArray = StringSplit($aFile, @CR)
    Else ;; unable to split the file
        If StringLen($aFile) Then
            Dim $aArray[2] = [1, $aFile] ; returns the whole file in one element
        Else
            Return SetError(2, 0, 0) ; File is empty
        EndIf
    EndIf

    ; now split 1D $aArray to 2D $aColumns according to delimiter

    Local $aColumns[$aArray[0]][1] ; create a new [2D] array with same nr. of lines of $aArray
    For $i = 1 To $aArray[0] ; scan all lines of the array
        $TempRow = StringSplit($aArray[$i], $delim, 2) ; split the line
        If UBound($TempRow) > UBound($aColumns, 2) Then ReDim $aColumns[$aArray[0]][UBound($TempRow)]
        For $ii = 0 To UBound($TempRow) - 1
            $aColumns[$i - 1][$ii] = $TempRow[$ii]
        Next
    Next
    Return $aColumns
EndFunc   ;==>_FileReadToArray_mod

Func _ExtractColumnFromArray($aArray, $col = 0)
    If 1 = UBound($aArray, 0) Then
        If $col = 0 Then
            Return $aArray ; already a single column array, send it back as is
        Else
            Return SetError(2, 0, -1) ; wrong column number
        EndIf
    EndIf
    If $col >= UBound($aArray, 2) Then Return SetError(2, 0, -1) ; wrong column number
    Local $aColumn[UBound($aArray)] ; create a new [1D] array
    For $i = 0 To UBound($aArray) - 1 ; scan all lines of the array
        $aColumn[$i] = $aArray[$i][$col]
    Next
    Return $aColumn
EndFunc   ;==>_ExtractColumnFromArray

Basic Example of use:

#include 'MultiPing.au3'
#include <array.au3>

MsgBox(0, "Hello", "The _nPing() function will ping ranges of IP addresses" & @CRLF & @CRLF & _
        "if called without arguments, it will try to detect your LAN parameters" & @CRLF & _
        "and then will ping all your LAN addresses, returninig a list of responding IP." & @CRLF & @CRLF & _
        "First  a detection of the LAN is performed and result displayed" & @CRLF & @CRLF & _
        "Press OK to detect:")

$lan = _LanParameters("", "", 1) ; with the first 2 argument blank, will detect local LAN
;                                     the third parameter 1 means show results

MsgBox(0, "Hello", "OK, now the full IP range will be pinged." & @CRLF & "In this example only the addresses of responding devices" & @CRLF & _
        "will be returned in the array (default)," & @CRLF & _
        "but the function can also return:" & @CRLF & _
        " 0 the whole list of IPs" & @CRLF & _
        " 1 only responding IPs" & @CRLF & _
        " 2 only not responding IPs" & @CRLF & @CRLF & _
        "Press OK to ping from IP " & $lan[5][1] & " to IP " & $lan[6][1])

; simplest way to use: without parameters
; will scan all your local LAN
; and display only responding IP
Local $Result = _nPing()
If @error Then MsgBox(0, "", "@error " & @error)
_ArrayDisplay($Result)

MsgBox(0, "", "Another way to use is to read a list of IP from a file (csv or single column)" & @CRLF & _
        "into an array and pass the array to the function" & @CRLF & _
        "if the array is 1D then is passed as is" & @CRLF & _
        "if the array is 2D (because a csv was read) the first column is passed," & @CRLF & _
        "but if you want to pass another column of the 2D array then" & @CRLF & _
        "just pass the column number (zero based) as second parameter (first column is 0)" & @CRLF & _
        "In this example the IP are in column 1" & @CRLF & @CRLF & _
        "Press OK to read the file")

; read the file in an array
; use the ";" as fields separator
$IPlist = _FileReadToArray_mod(".\IP_List.txt", ";")
If Not @error Then
    _ArrayDisplay($IPlist, "Data read from file") ; show array content
    $Result = _nPing($IPlist, 1); pass the second column to the function
    If @error Then MsgBox(0, "", "@error " & @error)
    _ArrayDisplay($Result) ; display the result of the pings
Else
    MsgBox(0, "", "@error " & @error)
EndIf

IP_List.txt

Google;173.194.36.50
AutoIT;87.106.181.57
YouTube;74.125.228.65
Google.com;74.125.224.72
Gmail.com;74.125.224.181
Bing.com;131.253.13.32
Hotmail.com;65.55.72.135
Yahoo.com;98.139.183.24
Amazon.com;72.21.211.176
Facebook.com;69.171.234.21
Facebook.com;69.63.176.13
Facebook.com;69.63.181.15
Facebook.com;69.63.184.142
Facebook.com;69.63.187.17
Facebook.com;69.63.187.18
Facebook.com;69.63.187.19
Facebook.com;69.63.181.11
Facebook.com;69.63.181.12
Twitter.com;199.59.148.10
Twitter.com;199.59.149.230
LinkedIn.com;216.52.242.86
WordPress.com;76.74.254.126
WordPress.org;72.233.56.138
Tumblr.com;174.121.194.34
Livejournal.com;209.200.154.225
Reddit.com;64.208.126.67
Imgur.com;173.231.140.219
Pinterest.com;23.21.142.179
Instagram.com;23.23.130.59
Stickam.com;67.201.54.151
Blogtv.com;84.22.170.149
Justin.tv;199.9.249.21
ChatRoulette.com;184.173.141.231
Newegg.com;216.52.208.187
ThePirateBay.org;194.71.107.50
Movie2k.com;109.163.226.240
PayPal.com;173.0.84.3
Botcrawl.com;174.132.77.244
Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 10 months later...

Just what I was looking for, well written and documented, Thank you

 

You are welcome :)

Here another (funny) and simple example of use (it monitor clients and set a "Green box" if is responding and a Red box if goes offline)

you can appreciate the "graphic" usefullness of this example script if you have at least 5 or so (better if more) clients connected to your LAN.

; this is to ping continuously a list of IP addresses, get and display ping result "live"
; it simulates the dos "ping -t" command but performed simultaneously on many IP
; presenting the results in a ListView highlighting not responding devices with a red box

#include <GUIConstantsEx.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <ListviewConstants.au3>

#include 'MultiPing.au3' ; <-- take this from the following link:
; http://www.autoitscript.com/forum/topic/156395-versatile-multi-ping

Local $IP_range = "" ; range to be pinged (leave it empty to ping all local lan)
Local $IP_mask = ""

Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "_button1")

Local $Win_X = 600, $Win_Y = 600 ; dimension of window
$PingGui = GUICreate("IP addresses monitor", $Win_X, $Win_Y, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_button1", $PingGui)
$listview = GUICtrlCreateListView("", 10, 10, $Win_X - 20, $Win_Y - 40)
GUICtrlSetFont(-1, 6)
GUICtrlSetStyle($listview, $LVS_ICON + $LVS_NOLABELWRAP)

; Generate colored square images
$hImage = _GUIImageList_Create(16, 16)
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFFFF00, 16, 16)) ; yellow
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFF0000, 16, 16)) ; red
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0x00FF00, 16, 16)) ; green

_GUICtrlListView_SetImageList($listview, $hImage, 0)

$button1 = GUICtrlCreateButton("Exit", 10, $Win_Y - 25, $Win_X - 20, 20)
GUICtrlSetTip(-1, "End of program")
GUICtrlSetOnEvent(-1, "_button1")
GUISetState(@SW_SHOW)

; $MyArray = _nPing($IP_range, $IP_mask, 1, 1) ;  first call is to generate the array
  $MyArray = _nPing($IP_range, $IP_mask, 1) ; first call is to generate the array (no name resolution)
;                                               this will search for all active IP devices
;                                               and make a "snapshot" in the $MyArrat

_ArrayDelete($MyArray, 0) ; remove first item
; _ArrayDisplay($MyArray)
_GUICtrlListView_BeginUpdate($listview)
_GUICtrlListView_AddArray($listview, $MyArray) ; and fill ListView
_GUICtrlListView_EndUpdate($listview)

While 1 ; continuously ping addresses of the snapshot previously generated
    Sleep(10)
    _nPing($MyArray, 0, 0, 0, "_refresh") ; PING required addresses and call the _refresh() function
    ;                                        for each terminated ping (reasults of ping are passed to function)
WEnd

Func _button1() ; Button 1 clicked
    Exit
EndFunc   ;==>_button1

Func _refresh($Params) ; this receive ping results and displays them in the ListView
    _GUICtrlListView_SetItemImage($listview, $Params[5], 0) ; set colour to Yellow
    Sleep(50) ; a little wait
    If $Params[4] = -1 Then ; Device not responding to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 1) ; set colour to RED
        _GUICtrlListView_EnsureVisible($listview, $Params[5]) ; Position view to this item
    Else ; Device responds to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 2) ; set colour to GREEN
    EndIf
EndFunc   ;==>_refresh

edit:

changed

$MyArray = _nPing($IP_range, $IP_mask, 1, 1) ;  first call is to generate the array

with

$MyArray = _nPing($IP_range, $IP_mask, 1) ;  first call is to generate the array

to disable name resolution (not needed in this example and performs faster initial scan)

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 1 month later...

Hi,  I am trying to sort of combine the two posted scripts from above, but I am not having success.

I was wanting to create a text file list of IP's that this script would read from, ping hte devices and display the results in colored squares.  I was hoping to have the left colum of the text file, which is the name associated with the IP to display under the colored box and not the IP address.

I thought I could stumble through it, but I am quickly seeing I don't have enough experience with this stuff.  Anybody have a chance to help me?

Thanks - Mike

 

Here is what I have:

 

; this is to ping continuously a list of IP addresses, get and display ping result "live"
; it simulates the dos "ping -t" command but performed simultaneously on many IP
; presenting the results in a ListView highlighting not responding devices with a red box

#include <GUIConstantsEx.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <ListviewConstants.au3>

#include 'MultiPing.au3' ; <-- take this from the following link:
; '?do=embed' frameborder='0' data-embedContent>>

; Local $IP_range = "" ; range to be pinged (leave it empty to ping all local lan)
; Local $IP_mask = ""


Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "_button1")

Local $Win_X = 600, $Win_Y = 600 ; dimension of window
$PingGui = GUICreate("IP addresses monitor", $Win_X, $Win_Y, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_button1", $PingGui)
$listview = GUICtrlCreateListView("", 10, 10, $Win_X - 20, $Win_Y - 40)
GUICtrlSetFont(-1, 6)
GUICtrlSetStyle($listview, $LVS_ICON + $LVS_NOLABELWRAP)

; Generate colored square images
$hImage = _GUIImageList_Create(16, 16)
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFFFF00, 16, 16)) ; yellow
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFF0000, 16, 16)) ; red
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0x00FF00, 16, 16)) ; green

_GUICtrlListView_SetImageList($listview, $hImage, 0)

$button1 = GUICtrlCreateButton("Exit", 10, $Win_Y - 25, $Win_X - 20, 20)
GUICtrlSetTip(-1, "End of program")
GUICtrlSetOnEvent(-1, "_button1")
GUISetState(@SW_SHOW)

$IPlist = _FileReadToArray_mod(".IP_List.txt") ; Reads text file for list of IP's

$MyArray = _nPing($IPlist, 1, 0); the ,1 is to pass the second column to the function,
;                                I don't know what the ,0 does, but without it I know the script will not scan through the list.

; $MyArray = _nPing($IP_range, 0, 1, 1) ;  first call is to generate the array
;  $MyArray = _nPing($IPlist, 0, 1) ; first call is to generate the array (no name resolution)
;                                               this will search for all active IP devices
;                                               and make a "snapshot" in the $MyArrat

_ArrayDelete($MyArray, 0) ; remove first item
; _ArrayDisplay($MyArray)
_GUICtrlListView_BeginUpdate($listview)
_GUICtrlListView_AddArray($listview, $IPlist) ; and fill ListView
_GUICtrlListView_EndUpdate($listview)

Func _button1() ; Button 1 clicked
    Exit
EndFunc   ;==>_button1

While 1 ; continuously ping addresses of the snapshot previously generated
    Sleep(10)
    _nPing($MyArray, 0, 0, 0, "_refresh") ; PING required addresses and call the _refresh() function
    ;                                        for each terminated ping (reasults of ping are passed to function)
 WEnd



Func _refresh($Params) ; this receive ping results and displays them in the ListView
    _GUICtrlListView_SetItemImage($listview, $Params[5], 0) ; set colour to Yellow
    Sleep(50) ; a little wait
    If $Params[4] = -1 Then ; Device not responding to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 1) ; set colour to RED
        _GUICtrlListView_EnsureVisible($listview, $Params[5]) ; Position view to this item
    Else ; Device responds to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 2) ; set colour to GREEN
    EndIf
 EndFunc   ;==>_refresh

Link to comment
Share on other sites

Hi,  I am trying to sort of combine the two posted scripts from above, but I am not having success.

I was wanting to create a text file list of IP's that this script would read from, ping hte devices and display the results in colored squares.  I was hoping to have the left colum of the text file, which is the name associated with the IP to display under the colored box and not the IP address.

I thought I could stumble through it, but I am quickly seeing I don't have enough experience with this stuff.  Anybody have a chance to help me?

Thanks - Mike

 

Here is what I have:

.......

 

Hi jsa272

if you already have a file with a list of IP then the code is simpler cause there is no need to generate them automatically by the function,

we just load the IP list from the file and then continuosly perform pings on all IP addresses.

try this:

; this is to ping continuously a list of IP addresses, get and display ping result "live"
; it simulates the dos "ping -t" command but performed simultaneously on many IP
; presenting the results in a ListView highlighting not responding devices with a red box

#include <GUIConstantsEx.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <ListviewConstants.au3>

#include 'MultiPing.au3' ; <-- take this from the following link:
; http://www.autoitscript.com/forum/topic/156395-versatile-multi-ping

Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "_button1")

Local $Win_X = 600, $Win_Y = 600 ; dimension of window
$PingGui = GUICreate("IP addresses monitor", $Win_X, $Win_Y, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_button1", $PingGui)
$listview = GUICtrlCreateListView("", 10, 10, $Win_X - 20, $Win_Y - 40)
GUICtrlSetFont(-1, 6)
GUICtrlSetStyle($listview, $LVS_ICON) ; + $LVS_NOLABELWRAP)

; Generate colored square images
$hImage = _GUIImageList_Create(16, 16)
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFFFF00, 16, 16)) ; yellow
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFF0000, 16, 16)) ; red
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0x00FF00, 16, 16)) ; green

_GUICtrlListView_SetImageList($listview, $hImage, 0)

$button1 = GUICtrlCreateButton("Exit", 10, $Win_Y - 25, $Win_X - 20, 20)
GUICtrlSetTip(-1, "End of program")
GUICtrlSetOnEvent(-1, "_button1")
GUISetState(@SW_SHOW)

$IPlist = _FileReadToArray_mod(".\IP_List.txt") ; Reads text file for list of IP's
;
; the above command, it loads in the $IPlist array the values contained in the file IP_List.txt
; values in the file should be separated by a semicolon, something like in the following example:
;
; hostname1;192.168.0.1
; hostname2;192.168.0.5
; hostnameX;10.59.7.200
; etc....
;
;  if values in the file are not separated by a semicolon, but another char is used, for example a comma,
;  then just pass it as second parameter of the function: $IPlist = _FileReadToArray_mod(".\IP_List.txt", ",")
;
_GUICtrlListView_BeginUpdate($listview)
_GUICtrlListView_AddArray($listview, $IPlist) ; fill ListView
_GUICtrlListView_EndUpdate($listview)

While 1 ; continuously ping addresses of the previously loaded file (IP_List.txt)
    Sleep(10)
    ;
    ;        $IPlist is the array loaded with all the IP to be pinged (a 2d array in this case)
    ;        |
    ;        |      1 means the IP are in the second column of the $IPlist array (first colun is nr. 0)
    ;        |      |
    ;        |      |  +-->  0 means return back an array loaded with results from all pinged addresses (responding and not responding)
    ;        |      |  |     if you use 1 then only responding addresses are loaded in the returned array [default]
    ;        |      |  |     if you use 2 then only NOT responding addresses are loaded in the returned array
    ;        |      |  |     In this case we do not need an  array to be returned, we only need to perform all pings and pass results
    ;        |      |  |     directly (on the fly) to the "_refresh" callback function that will refresh the listview
    ;        |      |  |
    ;        |      |  |  0 means NO lookup name resolution must be performed
    ;        |      |  |  |
    ;        |      |  |  |   +--> this is the callback function to be called for each pinged address each time the ping has finished
    ;        |      |  |  |   |    (see the MultiPing.au3 file for info on all passed params)
    ;        |      |  |  |   |    6 parameters are passed to this function, but only 2 are used by the called function in this case:
    ;        |      |  |  |   |    [4] roundtrip of the responding ping or -1 if IP is down
    ;        |      |  |  |   |    [5] Index (position) of this IP within the caller's passed array
    ;        |      |  |  |   |
    ;        v      v  v  v   v
    _nPing($IPlist, 1, 0, 0, "_refresh")
    ;
WEnd

Func _refresh($Params) ; this receive ping results and displays them in the ListView
    _GUICtrlListView_SetItemImage($listview, $Params[5], 0) ; set colour to Yellow
    Sleep(50) ; a little wait
    If $Params[4] = -1 Then ; Device not responding to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 1) ; set colour to RED
        _GUICtrlListView_EnsureVisible($listview, $Params[5]) ; Position view to this item
    Else ; Device responds to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 2) ; set colour to GREEN
    EndIf
EndFunc   ;==>_refresh

Func _button1() ; Button 1 clicked
    Exit
EndFunc   ;==>_button1

note that this is just a simple example of use, If hostnames are a bit long, then "aesthetical" issues can arise in the ListView

edit:

removed the $LVS_NOLABELWRAP style from ListView for a better display of the hostnames

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Chimp,

Thanks for the response back - thanks for also adding the remarks in there, that helps me understand nPing better. 

I have done some other slight modificaitons to fit my needs, but have run into something else I can't seem to accomplish.  I have added a sleep line so that it pings the devices every 15 minutes instead of continously, but now it would be nice to have a timestamp of the last time it pinged the devices in the list so one could look at the window and know that the script is still doing it's thing - otherwise you jsut see green boxes unless you happen to catch the boxes flicker yellow when it does it's round of pings.  Or if not a time stamp could like a 15 minute countdown timer display - that could work too.

Another thing I am trying to do is add a second button that if clicked would trigger the devices in the list to be ping'ed immediately. 

Func _button2()    ;Button to Refresh (ping devices) Now
   FuncName("_refresh")
EndFunc

I am not sure if FuncName is the appropriate function I should be using or if I need to be going to the While statement and not the refresh function portion of the script?

This is fun to be messing with and it's great get this as a tool!

Thanks for your help!

Mike

Link to comment
Share on other sites

.....

This is fun to be messing with and it's great get this as a tool!

....

 

something like this? ... ;)

; this is to ping every n minutes a list of IP addresses, get and display ping result "live"
; it simulates the dos "ping" command but performed simultaneously on many IP
; presenting the results in a ListView highlighting not responding devices with a red box

#include <GUIConstantsEx.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <ListviewConstants.au3>

#include 'MultiPing.au3' ; <-- take this from the following link:
; http://www.autoitscript.com/forum/topic/156395-versatile-multi-ping

Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "_button1")

Global $Timeout = 15 * 60000 ; 15 = minutes <----------------------- set timeout here

Local $Win_X = 600, $Win_Y = 600 ; dimension of window
$PingGui = GUICreate("IP addresses monitor", $Win_X, $Win_Y, -1, -1)
GUICtrlCreateLabel("Last scan performed at", 10, 7, 160, 15)
GUICtrlSetFont(-1, 12)
$LastScan = GUICtrlCreateLabel("", 180, 5, 50, 25)
GUICtrlSetFont(-1, 14)
GUICtrlCreateLabel("Next scan will start in ", 240, 7, 160, 15)
GUICtrlSetFont(-1, 12)
$Countdown = GUICtrlCreateLabel("00:00:00", 390, 5, 70, 25)
GUICtrlSetFont(-1, 14)
;
$button0 = GUICtrlCreateButton("Scan Now", 470, 5, 120, 20)
GUICtrlSetOnEvent(-1, "_ScanNow")
;
$button1 = GUICtrlCreateButton("Exit", 10, $Win_Y - 25, $Win_X - 20, 20)
GUICtrlSetTip(-1, "End of program")
GUICtrlSetOnEvent(-1, "_button1")
;
GUISetOnEvent($GUI_EVENT_CLOSE, "_button1", $PingGui)
;
$listview = GUICtrlCreateListView("", 10, 30, $Win_X - 20, $Win_Y - 60)
GUICtrlSetFont(-1, 6)
GUICtrlSetStyle($listview, $LVS_ICON) ; + $LVS_NOLABELWRAP)

; Generate colored square images
$hImage = _GUIImageList_Create(16, 16)
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFFFF00, 16, 16)) ; yellow
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFF0000, 16, 16)) ; red
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0x00FF00, 16, 16)) ; green

_GUICtrlListView_SetImageList($listview, $hImage, 0)

GUISetState(@SW_SHOW)

$IPlist = _FileReadToArray_mod(".\IP_List.txt") ; Reads text file for list of IP's
;
; the above command, it loads in the $IPlist array the values contained in the file IP_List.txt
; values in the file should be separated by a semicolon, something like in the following example:
;
; hostname1;192.168.0.1
; hostname2;192.168.0.5
; hostnameX;10.59.7.200
; etc....
;
;  if values in the file are not separated by a semicolon, but another char is used, for example a comma,
;  then just pass it as second parameter of the function: $IPlist = _FileReadToArray_mod(".\IP_List.txt", ",")
;
_GUICtrlListView_BeginUpdate($listview)
_GUICtrlListView_AddArray($listview, $IPlist) ; fill ListView
_GUICtrlListView_EndUpdate($listview)
; _Stopwatch(3) ; reset counter to 0 and start counting
Global $metronome = 0 ; metronome
Global $hourglass = $Timeout ; turn the hourglass
_ScanNow() ; ping devices at startup
;
While 1 ; main loop
    $hourglass = $Timeout - _Stopwatch() ; sand flowing down in the hourglass
    If $hourglass <= 0 Then ; no more sand
        _ScanNow() ; ping devices
    EndIf
    If $metronome <> Int(_Stopwatch() / 1000) Then ; refresh counter every second
        $metronome = Int(_Stopwatch() / 1000)
        GUICtrlSetData($Countdown, hhmmss($hourglass))
    EndIf
    Sleep(250)
WEnd

Func _ScanNow() ; performs immediate multiping on devices contained in previously loaded file (IP_List.txt)
    GUICtrlSetData($Countdown, "00:00:00") ; reset countdown display
    _Stopwatch(2) ; reset stopwatch to 0 and stop counting
    ;
    ;        $IPlist is the array loaded with all the IP to be pinged (a 2d array in this case)
    ;        |
    ;        |      1 means the IP are in the second column of the $IPlist array (first colun is nr. 0)
    ;        |      |
    ;        |      |  +-->  0 means return back an array loaded with results from all pinged addresses (responding and not responding)
    ;        |      |  |     if you use 1 then only responding addresses are loaded in the returned array [default]
    ;        |      |  |     if you use 2 then only NOT responding addresses are loaded in the returned array
    ;        |      |  |     In this case we do not need an  array to be returned, we only need to perform all pings and pass results
    ;        |      |  |     directly (on the fly) to the "_refresh" callback function that will refresh the listview
    ;        |      |  |
    ;        |      |  |  0 means NO lookup name resolution must be performed
    ;        |      |  |  |
    ;        |      |  |  |   +--> this is the callback function to be called for each pinged address each time the ping has finished
    ;        |      |  |  |   |    (see the MultiPing.au3 file for info on all passed params)
    ;        |      |  |  |   |    6 parameters are passed to this function, but only 2 are used by the called function in this case:
    ;        |      |  |  |   |    [4] roundtrip of the responding ping or -1 if IP is down
    ;        |      |  |  |   |    [5] Index (position) of this IP within the caller's passed array
    ;        |      |  |  |   |
    ;        v      v  v  v   v
    _nPing($IPlist, 1, 0, 0, "_refresh") ; ping all devices
    ;
    $hourglass = $Timeout ; reset and turn the hourglass
    _Stopwatch(3); reset counter to 0 and restart counting
    GUICtrlSetData($LastScan, @HOUR & ":" & @MIN) ; set last scan time
EndFunc   ;==>_ScanNow

Func _refresh($Params) ; this receive ping results and displays them in the ListView
    _GUICtrlListView_SetItemImage($listview, $Params[5], 0) ; set colour to Yellow
    Sleep(50) ; a little wait
    If $Params[4] = -1 Then ; Device not responding to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 1) ; set colour to RED
        _GUICtrlListView_EnsureVisible($listview, $Params[5]) ; Position view to this item
    Else ; Device responds to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 2) ; set colour to GREEN
    EndIf
EndFunc   ;==>_refresh

Func hhmmss($hourglass) ; convert $hourglass to hh:mm:ss
    $totsec = Int($hourglass / 1000) ; ms to sec
    $hr = Int($totsec / 3600) ; hours
    $mn = Int(($totsec - ($hr * 3600)) / 60) ; minutes
    $sc = Int(($totsec - ($hr * 3600) - ($mn * 60))) ; seconds
    Return StringFormat("%02s", $hr) & ":" & StringFormat("%02s", $mn) & ":" & StringFormat("%02s", $sc)
EndFunc   ;==>hhmmss

Func _button1() ; Button 1 clicked
    Exit
EndFunc   ;==>_button1

; #FUNCTION# (snippet) ==========================================================================================================
; Name...........: _Stopwatch (http://www.autoitscript.com/forum/topic/161337-simple-stopwatch-udf/)
; Description ...: returns the number of milliseconds counted (according to actions requests by caller)
; Syntax.........: _Stopwatch([$action])
; Parameters ....: $action: 0 - pause counting
;                           1 - resume counting
;                           2 - reset counter to 0 and stops
;                           3 - reset counter to 0 and start counting
;                           4 - (default) just ruturns actual counting value and status (status in @extended)
;
; Return values .: number of milliseconds in counter
;                  @extended contains paused status (1 or 0)
;                  1 if stopwatch is in pause
;                  0 if stopwatch is counting
;
; Author ........:
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: yes
; ===============================================================================================================================

Func _Stopwatch($ToggleTo = 4)
    Static Local $Paused = True
    Static Local $Stopwatch = 0
    Static Local $TotalTime = 0
    Switch $ToggleTo
        Case 0 ; pause counter
            If $Paused Then
                SetExtended($Paused) ; $Paused status
                Return $TotalTime ; already paused, just return current $TotalTime
            Else
                $TotalTime += TimerDiff($Stopwatch)
                $Paused = True
                SetExtended($Paused)
                Return $TotalTime
            EndIf
        Case 1 ; unpause counter
            If $Paused Then
                $Stopwatch = TimerInit()
                $Paused = False
                SetExtended($Paused)
                Return $TotalTime
            Else
                SetExtended($Paused)
                Return $TotalTime + TimerDiff($Stopwatch)
            EndIf
        Case 2 ; reset to 0 and pause
            $Paused = True
            $TotalTime = 0
            SetExtended($Paused)
            Return $TotalTime
        Case 3 ; reset to 0 and restart
            $Paused = False
            $TotalTime = 0
            $Stopwatch = TimerInit()
            SetExtended($Paused)
            Return $TotalTime
        Case 4 ; return status
            SetExtended($Paused)
            If $Paused Then
                Return $TotalTime
            Else
                Return $TotalTime + TimerDiff($Stopwatch)
            EndIf
    EndSwitch
EndFunc   ;==>_Stopwatch
Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 10 months later...

Hi, I like this scripts so much, but i have one comment on the ping or refresh. Lets say I have 1000 host to monitor, when I run it, it will takes around probably 5 minutes for it to went over all the list one by one as it loop the array. Is there a way that we split the job for example every 100 hosts will run in separate job:

 

Example for current is:

Job 1 = from 1 to 1000 (Lets say 10 minute)

Example ideal:

1000 host, split to every 100 host per job and run simultaneously

Job 1 = from 1 to 100

Job 2 = from 101 to 200

Job 3 = from 201 to 300

Job 4 = from 301 to 400

 

Of all the job run at the same time it will only takes 1 minute.

Link to comment
Share on other sites

hi AaronOoi

The _nPing function doesn't ping addresses stepping "over all the list one by one as it loop the array", but it already pings more addresses simultaneously. Precisely it spawns 20 pings at once. (have a look to the task manager while the function is running and you will see 20 Ping process running).

So if you would run 4 instances of the _nPing() function, it would result in 80 pings running at the same time.

I think that over a certain number of simultaneous pings the overall performances could worsen instead of improve, this because of the overload on the lan card of your pc.
Anyway, if you want try such stress-tests, you have to simply increase the value of the variable $MAX_PROCESS on the first lines of the _nPing() function.
Now it's calibrated on the value of 20 simultaneous pings, but you can change this value as you like (within sensate values of course), maybe you can increase this value to 80 hoping to obtain better performances..... (?)

well, if you do some testing by increasing the $MAX_PROCESS value, I would be interested to know the obtained results.

P.S. keep a fire extinguisher on hand for any possible outbreak of fire on the network card....:P

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 1 year later...
On 11/8/2014 at 8:26 AM, Chimp said:

 

Hi jsa272

if you already have a file with a list of IP then the code is simpler cause there is no need to generate them automatically by the function,

we just load the IP list from the file and then continuosly perform pings on all IP addresses.

try this:

; this is to ping continuously a list of IP addresses, get and display ping result "live"
; it simulates the dos "ping -t" command but performed simultaneously on many IP
; presenting the results in a ListView highlighting not responding devices with a red box

#include <GUIConstantsEx.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <ListviewConstants.au3>

#include 'MultiPing.au3' ; <-- take this from the following link:
; http://www.autoitscript.com/forum/topic/156395-versatile-multi-ping

Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "_button1")

Local $Win_X = 600, $Win_Y = 600 ; dimension of window
$PingGui = GUICreate("IP addresses monitor", $Win_X, $Win_Y, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_button1", $PingGui)
$listview = GUICtrlCreateListView("", 10, 10, $Win_X - 20, $Win_Y - 40)
GUICtrlSetFont(-1, 6)
GUICtrlSetStyle($listview, $LVS_ICON) ; + $LVS_NOLABELWRAP)

; Generate colored square images
$hImage = _GUIImageList_Create(16, 16)
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFFFF00, 16, 16)) ; yellow
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFF0000, 16, 16)) ; red
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0x00FF00, 16, 16)) ; green

_GUICtrlListView_SetImageList($listview, $hImage, 0)

$button1 = GUICtrlCreateButton("Exit", 10, $Win_Y - 25, $Win_X - 20, 20)
GUICtrlSetTip(-1, "End of program")
GUICtrlSetOnEvent(-1, "_button1")
GUISetState(@SW_SHOW)

$IPlist = _FileReadToArray_mod(".\IP_List.txt") ; Reads text file for list of IP's
;
; the above command, it loads in the $IPlist array the values contained in the file IP_List.txt
; values in the file should be separated by a semicolon, something like in the following example:
;
; hostname1;192.168.0.1
; hostname2;192.168.0.5
; hostnameX;10.59.7.200
; etc....
;
;  if values in the file are not separated by a semicolon, but another char is used, for example a comma,
;  then just pass it as second parameter of the function: $IPlist = _FileReadToArray_mod(".\IP_List.txt", ",")
;
_GUICtrlListView_BeginUpdate($listview)
_GUICtrlListView_AddArray($listview, $IPlist) ; fill ListView
_GUICtrlListView_EndUpdate($listview)

While 1 ; continuously ping addresses of the previously loaded file (IP_List.txt)
    Sleep(10)
    ;
    ;        $IPlist is the array loaded with all the IP to be pinged (a 2d array in this case)
    ;        |
    ;        |      1 means the IP are in the second column of the $IPlist array (first colun is nr. 0)
    ;        |      |
    ;        |      |  +-->  0 means return back an array loaded with results from all pinged addresses (responding and not responding)
    ;        |      |  |     if you use 1 then only responding addresses are loaded in the returned array [default]
    ;        |      |  |     if you use 2 then only NOT responding addresses are loaded in the returned array
    ;        |      |  |     In this case we do not need an  array to be returned, we only need to perform all pings and pass results
    ;        |      |  |     directly (on the fly) to the "_refresh" callback function that will refresh the listview
    ;        |      |  |
    ;        |      |  |  0 means NO lookup name resolution must be performed
    ;        |      |  |  |
    ;        |      |  |  |   +--> this is the callback function to be called for each pinged address each time the ping has finished
    ;        |      |  |  |   |    (see the MultiPing.au3 file for info on all passed params)
    ;        |      |  |  |   |    6 parameters are passed to this function, but only 2 are used by the called function in this case:
    ;        |      |  |  |   |    [4] roundtrip of the responding ping or -1 if IP is down
    ;        |      |  |  |   |    [5] Index (position) of this IP within the caller's passed array
    ;        |      |  |  |   |
    ;        v      v  v  v   v
    _nPing($IPlist, 1, 0, 0, "_refresh")
    ;
WEnd

Func _refresh($Params) ; this receive ping results and displays them in the ListView
    _GUICtrlListView_SetItemImage($listview, $Params[5], 0) ; set colour to Yellow
    Sleep(50) ; a little wait
    If $Params[4] = -1 Then ; Device not responding to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 1) ; set colour to RED
        _GUICtrlListView_EnsureVisible($listview, $Params[5]) ; Position view to this item
    Else ; Device responds to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 2) ; set colour to GREEN
    EndIf
EndFunc   ;==>_refresh

Func _button1() ; Button 1 clicked
    Exit
EndFunc   ;==>_button1

note that this is just a simple example of use, If hostnames are a bit long, then "aesthetical" issues can arise in the ListView

edit:

removed the $LVS_NOLABELWRAP style from ListView for a better display of the hostnames

Hey Chimp, First of thank you for directing me to your script. It is great. Is there way using the .txt to change different number inside of it

For example

like

10.20.30.1

10.20.30.1

 

10.21.31.1

But without changing the .txt file for every one

Link to comment
Share on other sites

Just now, Chimp said:

Hi @dascondor,

I think I don't understand your question, what would you like to do to the IP addresses contained in txt file ?? could you explain better? thanks

@Chimp

Sorry, I'm sorry  it didn't take the rest of it.

I wanna be able to Change the 2nd and 3rd octet of the IP address with out physically changing the changing the .txt file

So for example:

10.20.30.1

10.20.30.2

10.20.30.3

And my list is Fairly Long and used my some people that are not tech savy

But then I need to change the IP address like this

10.63.78.1

10.63.78.2

10.63.78.3

And still keep the same names with it.

I thought you might know a way of changing part of it

like

_nPing (10.("$oct{2}") . ("$oct{3}") . IP_List.txt ,  1, 0, 0, "_refresh")

And the .txt file look like this

router; 10. xxx. xxx. 1

WAP; 10. xxx. xxx. 2

Computer 1; 10. xxx. xxx. 3

 

What do you think???

 

Link to comment
Share on other sites

@dascondor, the _nPing function allows various ways to pass ranges of IP addresses just specifing one IP address and the subnet mask of a LAN to ping all devices belonging to that LAN, or by using a syntax to declare ranges of IP as explained in the headerof the function (example 192.161.0-1.*), but if you want pass a list of "random" IP addresses then you have to load "manually" the addresses into a file and then pass the ready made file to the function that will be happy to ping all those addresses for you :)

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

On 11/8/2014 at 8:26 AM, Chimp said:

 

Hi jsa272

if you already have a file with a list of IP then the code is simpler cause there is no need to generate them automatically by the function,

we just load the IP list from the file and then continuosly perform pings on all IP addresses.

try this:

; this is to ping continuously a list of IP addresses, get and display ping result "live"
; it simulates the dos "ping -t" command but performed simultaneously on many IP
; presenting the results in a ListView highlighting not responding devices with a red box

#include <GUIConstantsEx.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <ListviewConstants.au3>

#include 'MultiPing.au3' ; <-- take this from the following link:
; http://www.autoitscript.com/forum/topic/156395-versatile-multi-ping

Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "_button1")

Local $Win_X = 600, $Win_Y = 600 ; dimension of window
$PingGui = GUICreate("IP addresses monitor", $Win_X, $Win_Y, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_button1", $PingGui)
$listview = GUICtrlCreateListView("", 10, 10, $Win_X - 20, $Win_Y - 40)
GUICtrlSetFont(-1, 6)
GUICtrlSetStyle($listview, $LVS_ICON) ; + $LVS_NOLABELWRAP)

; Generate colored square images
$hImage = _GUIImageList_Create(16, 16)
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFFFF00, 16, 16)) ; yellow
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFF0000, 16, 16)) ; red
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0x00FF00, 16, 16)) ; green

_GUICtrlListView_SetImageList($listview, $hImage, 0)

$button1 = GUICtrlCreateButton("Exit", 10, $Win_Y - 25, $Win_X - 20, 20)
GUICtrlSetTip(-1, "End of program")
GUICtrlSetOnEvent(-1, "_button1")
GUISetState(@SW_SHOW)

$IPlist = _FileReadToArray_mod(".\IP_List.txt") ; Reads text file for list of IP's
;
; the above command, it loads in the $IPlist array the values contained in the file IP_List.txt
; values in the file should be separated by a semicolon, something like in the following example:
;
; hostname1;192.168.0.1
; hostname2;192.168.0.5
; hostnameX;10.59.7.200
; etc....
;
;  if values in the file are not separated by a semicolon, but another char is used, for example a comma,
;  then just pass it as second parameter of the function: $IPlist = _FileReadToArray_mod(".\IP_List.txt", ",")
;
_GUICtrlListView_BeginUpdate($listview)
_GUICtrlListView_AddArray($listview, $IPlist) ; fill ListView
_GUICtrlListView_EndUpdate($listview)

While 1 ; continuously ping addresses of the previously loaded file (IP_List.txt)
    Sleep(10)
    ;
    ;        $IPlist is the array loaded with all the IP to be pinged (a 2d array in this case)
    ;        |
    ;        |      1 means the IP are in the second column of the $IPlist array (first colun is nr. 0)
    ;        |      |
    ;        |      |  +-->  0 means return back an array loaded with results from all pinged addresses (responding and not responding)
    ;        |      |  |     if you use 1 then only responding addresses are loaded in the returned array [default]
    ;        |      |  |     if you use 2 then only NOT responding addresses are loaded in the returned array
    ;        |      |  |     In this case we do not need an  array to be returned, we only need to perform all pings and pass results
    ;        |      |  |     directly (on the fly) to the "_refresh" callback function that will refresh the listview
    ;        |      |  |
    ;        |      |  |  0 means NO lookup name resolution must be performed
    ;        |      |  |  |
    ;        |      |  |  |   +--> this is the callback function to be called for each pinged address each time the ping has finished
    ;        |      |  |  |   |    (see the MultiPing.au3 file for info on all passed params)
    ;        |      |  |  |   |    6 parameters are passed to this function, but only 2 are used by the called function in this case:
    ;        |      |  |  |   |    [4] roundtrip of the responding ping or -1 if IP is down
    ;        |      |  |  |   |    [5] Index (position) of this IP within the caller's passed array
    ;        |      |  |  |   |
    ;        v      v  v  v   v
    _nPing($IPlist, 1, 0, 0, "_refresh")
    ;
WEnd

Func _refresh($Params) ; this receive ping results and displays them in the ListView
    _GUICtrlListView_SetItemImage($listview, $Params[5], 0) ; set colour to Yellow
    Sleep(50) ; a little wait
    If $Params[4] = -1 Then ; Device not responding to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 1) ; set colour to RED
        _GUICtrlListView_EnsureVisible($listview, $Params[5]) ; Position view to this item
    Else ; Device responds to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 2) ; set colour to GREEN
    EndIf
EndFunc   ;==>_refresh

Func _button1() ; Button 1 clicked
    Exit
EndFunc   ;==>_button1

note that this is just a simple example of use, If hostnames are a bit long, then "aesthetical" issues can arise in the ListView

edit:

removed the $LVS_NOLABELWRAP style from ListView for a better display of the hostnames

 

@Chimp

 

So I wonder does thing have any data you can save out to; does it create date that could be saved to an outside file? If not that is okay.I'm simply trying to make it more functional. (I just don't understand how the gui understand ListView.)

Link to comment
Share on other sites

@dascondor

The _nPing function() performs the Ping on all the clients contained in the passed array and collects all results in the returned array

so, when you call the nPing function, it takes a certain amount of time to terminate, depending on the number of elements in the array and the roundtrip of each single device, and at the end of all the pings, it returns to you an array loaded with all the results.

Furthermore, there is a bonus extra, that is, during the time used by the function to complete the job, instead of just waiting the result, you can use in the meanwhile, the "CallBack" function so to be notified each time a single ping terminate it's job

In this way you can "see" on live what's going on also before to receive the final result in the array. I used this CallBack feature to update the ListView, live.

In the above demo,
1) I don't make use of the returned array, since, as you can see in the listing, I just call the nPing function without a variable to get the returned array.
2) I use only the callBack function "_refresh" just to update the ListView.
3) I repeat points 1 and 2 in an endless loop just to continuously show, using the colored squares in the ListView, the status of the pinged devices.

Now, if you want instead for example make just one scan and then save all the results to a file on the disk, you can simply call the nPing function just one time, and then write the data you need from the returned array to the disk file.
(To semplify further, you could also remove all the ListView stuff from the gui and also remove the "_refresh" call back function from the nPing. In this way, when no call back function is specified, by default is shown a progress bar. Anyway I leave also the listview just to show how to make use of both functionalities)

Here is a reduced listing to show how to:

#include <GUIConstantsEx.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <ListviewConstants.au3>

#include 'MultiPing.au3' ; <-- take this from the following link:
; http://www.autoitscript.com/forum/topic/156395-versatile-multi-ping

Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "_button1")

Local $Win_X = 600, $Win_Y = 600 ; dimension of window
$PingGui = GUICreate("IP addresses monitor", $Win_X, $Win_Y, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_button1", $PingGui)
$listview = GUICtrlCreateListView("", 10, 10, $Win_X - 20, $Win_Y - 40)
GUICtrlSetFont(-1, 6)
GUICtrlSetStyle($listview, $LVS_ICON) ; + $LVS_NOLABELWRAP)

; Generate colored square images
$hImage = _GUIImageList_Create(16, 16)
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFFFF00, 16, 16)) ; yellow
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0xFF0000, 16, 16)) ; red
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($listview, 0x00FF00, 16, 16)) ; green

_GUICtrlListView_SetImageList($listview, $hImage, 0)

$button1 = GUICtrlCreateButton("Exit", 10, $Win_Y - 25, $Win_X - 20, 20)
GUICtrlSetTip(-1, "End of program")
GUICtrlSetOnEvent(-1, "_button1")
GUISetState(@SW_SHOW)

$IPlist = _FileReadToArray_mod(".\IP_List.txt") ; Reads text file for list of IP's
;
_GUICtrlListView_BeginUpdate($listview)
_GUICtrlListView_AddArray($listview, $IPlist) ; fill ListView
_GUICtrlListView_EndUpdate($listview)

;While 1
; perform Pings and update ListView by the "_refresh" callback function
$aFinalResult = _nPing($IPlist, 1, 0, 0, "_refresh")
_ArrayDisplay($aFinalResult) ; this is the result of all the pings

; Now Write a sample of data to a file on disk:
; ---------------------------------------------
$hFile = FileOpen("PingResults.csv", 2) ; $FO_OVERWRITE (2) = Write mode (erase previous contents)
For $i = 1 To $aFinalResult[0][0]
    $sResult = $aFinalResult[$i][0] & "," ; address of device
    If $aFinalResult[$i][2] <> -1 Then
        $sResult &= "OnLine"
    Else
        $sResult &= "OffLine"
    EndIf

    FileWriteLine($hFile, $sResult)
Next

FileFlush($hFile)
FileClose($hFile)

 ShellExecute("PingResults.csv") ; open the csv (with excel)

; WEnd

Func _refresh($Params) ; this receive ping results and displays them in the ListView
    _GUICtrlListView_SetItemImage($listview, $Params[5], 0) ; set colour to Yellow
    Sleep(50) ; a little wait
    If $Params[4] = -1 Then ; Device not responding to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 1) ; set colour to RED
        _GUICtrlListView_EnsureVisible($listview, $Params[5]) ; Position view to this item
    Else ; Device responds to ping
        _GUICtrlListView_SetItemImage($listview, $Params[5], 2) ; set colour to GREEN
    EndIf
EndFunc   ;==>_refresh

Func _button1() ; Button 1 clicked
    Exit
EndFunc   ;==>_button1

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

16 hours ago, dascondor said:

@Chimp

...What would I need to add to add device names to it?....

Set the fourth parameter of the nPing function to 1, so the IP address is also resolved in the host name

$aFinalResult = _nPing($IPlist, 1, 0, 1, "_refresh")

You will find the host name in the second column of the returned array.

the returned array has the following columns (1 based):

+-------------------------+-------------------------+-------------------------+-------------------------+
| IP address              | [hostname]              | roundtrip (or -1)       | index                   |
+-------------------------+-------------------------+-------------------------+-------------------------+

If instead you want to get the device names from your original file then what you need is the value in the fourth column of the returned array. This number tells you the line number of the original array that this ping result is referring to.
so, to get the device name from the original file just do like this:

$sHost = $IPlist[$aFinalResult[$i][3]][0]

P.S.

Heve a look to the function headr, all this, and other infos, are all explained in the function header.

 

16 hours ago, dascondor said:

Thank you very much for your Time and Expertise.

You are welcome  :)

Edited by Chimp
added explanations about the fourth column (index) of the returned array

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...