Jump to content

Progress Bar during Ping?


 Share

Recommended Posts

I am putting together a little console for some people at my company. Part of it involves pinging other computers, which works fine. I wanted to make it little more fancy and include a progress bar that updates during the Ping even though it's only a few seconds long (i.e. it gets to 100% if the Ping times out, and it stops progressing if the Ping returns before then).

Since program control waits at the Ping command, I can't use _Timer_Init & _Timer_Diff or similar functions because those would need to be in a loop which couldn't run simultaneously with the Ping. The obvious solution was to use _Timer_SetTimer just before the Ping and provide the callback function for it to update the progress bar. However, it seems that the Ping command seems to effectively stall the entry to the callback function until the Ping returns. And so, I'm stuck. Unless I want to try sending the Ping out through the windows command interpreter, then capturing and parsing the output. Yuk.

I welcome any and all solutions! I can appreciate the small elegant ones, but I'll settle for Big and Ugly!

Link to comment
Share on other sites

Thank you for the reply monoceres. I gave it a go, but unfortunately I got the same result. The timer callback seems to be blocked during this version of ping too. Thanks again for the reply.

The only metric of progress when pinging is the number of attempts.

#Include <GuiEdit.au3>
#include <GUIConstants.au3>

Const $numPings = 20
Const $host = "www.google.com"

GUICreate("My GUI")  ; will create a dialog box that when displayed is centered
GUISetState (@SW_SHOW)       ; will display an empty dialog box

GuiCtrlCreateLabel("Ping progress:", 10, 10, 100,20)
$tasks = GuiCtrlCreateLabel("", 110, 10, 100,20)

$progress = GUICtrlCreateProgress(10,50,330,20)
$percent = GuiCtrlCreateLabel("100%", 350, 53, 100,20)

$log = GuiCtrlCreateEdit("",10,80,380,310)

HttpSetProxy (1)


For $X = 1 to $numPings
    
    $totalTimer = TimerInit()
    
    $relativePercent = ($X/$numPings) * 100
    
    ;Update completed task count
    GuiCtrlSetData($tasks,$X & "/" & $numPings)
    
    ;Update progress bar
    GuiCtrlSetData($progress,$relativePercent)
    
    ;Update progress percent
    GuiCtrlSetData($percent, $relativePercent & "%")
    
    _GUICtrlEdit_AppendText($log, "Pinging host (" & $host & "): " & $X & "/" & $numPings & @CRLF)
    
    $result = Ping($host)
    ConsoleWrite($result & @CRLF)
    If $result <> 0 Then
        _GUICtrlEdit_AppendText($log, "OK")
    Else
        _GUICtrlEdit_AppendText($log, "FAIL")
    EndIf
    
    _GUICtrlEdit_AppendText($log, " (" & $result & "ms)" & @CRLF)

    ;Extra space
    _GUICtrlEdit_AppendText($log, @CRLF)
Next

; Run the GUI until the dialog is closed
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Wend
Link to comment
Share on other sites

Maybe...

$gui = GUICreate("My GUI2")
GUISetState()

Run_Progess("My GUI2")

While GUIGetMsg() <> -3
WEnd

Func Run_Progess($Title = "My GUI")
    $Location = @ScriptDir & "\Progress.au3"
    FileDelete($Location)
    $Program = 'ProgressOn("MaXoFF", "Now Pinging From " & @ComputerName, "Valuater... 8)")' & @CRLF _
             & 'Local $Percent = 100 / 20, $loop = 0' & @CRLF _
             & 'While WinExists("' & $Title & '")' & @CRLF _
             & '    $loop += 1' & @CRLF _
             & '    ProgressSet($Percent * $loop)' & @CRLF _
             & '    If $Percent * $loop >= 100 Then $loop = 0' & @CRLF _
             & '    Sleep(700)' & @CRLF _
             & 'WEnd'
    FileWrite($Location, $Program)
    If @Compiled = 1 Then
        $file_exe = FileGetShortName(@AutoItExe & ' /AutoIt3ExecuteScript "' & $Location & '"')
        Run($file_exe)
    Else
        $file_au3 = FileGetShortName($Location)
        Run(@AutoItExe & " " & $file_au3, "", @SW_HIDE)
    EndIf
EndFunc   ;==>Run_Progess

It's the idea, you can change to "While" what-ever :)

8)

Edited by Valuater

NEWHeader1.png

Link to comment
Share on other sites

Thank you for the reply monoceres. I gave it a go, but unfortunately I got the same result. The timer callback seems to be blocked during this version of ping too. Thanks again for the reply.

You can use a timer if you call ping with Run. Here is a hurried example.

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <timers.au3>
#include <Constants.au3>
#Region ### START Koda GUI section ### Form=
$Form3 = GUICreate("Form3", 413, 298, 303, 219)
$Label1 = GUICtrlCreateLabel("Label1", 56, 32, 36, 17)
$Btn = GUICtrlCreateButton("ping", 30, 100, 100, 22)
Global $ii = 0
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Btn
            MyPing()
            
    EndSwitch
WEnd


Func show($a, $b, $c, $d)
    GUICtrlSetData($Label1, $ii)
    $ii += 1
EndFunc  ;==>show

Func MyPing()
    $t1 = _Timer_SetTimer($Form3, 100, "show")
    Local $foo = Run('ping.exe "google.com"', @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)

; Calling with no 2nd arg closes stream
    StdinWrite($foo)

; Read from child's STDOUT and show
    Local $data
    While True
        $data &= StdoutRead($foo)
        If @error Then ExitLoop
        Sleep(25)
    WEnd
    _Timer_KillAllTimers($Form3)
    MsgBox(0, "Debug", $data)
EndFunc  ;==>MyPing
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

You can use a timer if you call ping with Run. Here is a hurried example.

#include <GUIConstantsEx.au3>
 #include <StaticConstants.au3>
 #include <WindowsConstants.au3>
 #include <GUIConstants.au3>
 #include <timers.au3>
 #include <Constants.au3>
 #Region ### START Koda GUI section ### Form=
 $Form3 = GUICreate("Form3", 413, 298, 303, 219)
 $Label1 = GUICtrlCreateLabel("Label1", 56, 32, 36, 17)
 $Btn = GUICtrlCreateButton("ping", 30, 100, 100, 22)
 Global $ii = 0
 GUISetState(@SW_SHOW)
 #EndRegion ### END Koda GUI section ###
 
 While 1
     $nMsg = GUIGetMsg()
     Switch $nMsg
         Case $GUI_EVENT_CLOSE
             Exit
         Case $Btn
             MyPing()
             
     EndSwitch
 WEnd
 
 
 Func show($a, $b, $c, $d)
     GUICtrlSetData($Label1, $ii)
     $ii += 1
 EndFunc ;==>show
 
 Func MyPing()
     $t1 = _Timer_SetTimer($Form3, 100, "show")
     Local $foo = Run('ping.exe "google.com"', @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
 
; Calling with no 2nd arg closes stream
     StdinWrite($foo)
 
; Read from child's STDOUT and show
     Local $data
     While True
         $data &= StdoutRead($foo)
         If @error Then ExitLoop
         Sleep(25)
     WEnd
     _Timer_KillAllTimers($Form3)
     MsgBox(0, "Debug", $data)
 EndFunc ;==>MyPing
Nice results... But Mines "Prettier"... :)

8)

NEWHeader1.png

Link to comment
Share on other sites

Nice results... But Mines "Prettier"... :o

8)

Yes it is. I don't get many points for being pretty :D

:)

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Actually, the OP got a great "Welcome to the Autoit Forums" from us!

and thus far no acknowledgment..???

BTW which one did you prefer???

8)

I want to play too!

#include <GDIPlus.au3>

Global $Hosts[7] = ["www.google.com", "en.wikipedia.org", "www.ati.com", _
        "www.youtube.com", "www.adobe.com", "localhost", "www.nvidia.com"]

Global Const $width = 600
Global Const $height = 400
Global $Progress = 0; 0-100 %
Global $PingsToMake = 33
Global $PingsMade = 0

Global $TextQueue



Opt("GUIOnEventMode", 1)
$hwnd = GUICreate("Ping", $width, $height)
GUISetOnEvent(-3, "close")
GUISetState()

_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
_GDIPlus_GraphicsSetSmoothingMode($backbuffer, 4)

$redbrush = _GDIPlus_BrushCreateSolid(0xFFAA0000)
$greenbrush = _GDIPlus_BrushCreateSolid(0xFF00AA00)
$whitebrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)

$family = _GDIPlus_FontFamilyCreate("Arial")
$font = _GDIPlus_FontCreate($family, 16)

$sformat = _GDIPlus_StringFormatCreate()
_GDIPlus_StringFormatSetAlign($sformat, 1)
$sformat2 = _GDIPlus_StringFormatCreate()

_GDIPlus_GraphicsClear($backbuffer)
_GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)


AdlibEnable("pinger", 1000)

Do
    _GDIPlus_GraphicsClear($backbuffer, 0x0F000000)
    
    If $TextQueue <> "" Then
        
        Do
            $y = Random(0, $height - 25, 1)
        Until $y < ($height / 2 - 75) Or $y > ($height / 2 - 75) + 150
        
        
        _GDIPlus_GraphicsDrawStringEx($backbuffer, $TextQueue, $font, _GDIPlus_RectFCreate(Random(0, $width - 200, 1), $y, 300, 300), $sformat2, $whitebrush)
        $TextQueue = ""
    EndIf
    

    
    _GDIPlus_GraphicsFillEllipse($backbuffer, $width / 2 - 75, $height / 2 - 75, 150, 150, $redbrush)
    _GDIPlus_GraphicsFillPie($backbuffer, $width / 2 - 75, $height / 2 - 75, 150, 150, -90, 3.6 * $Progress, $greenbrush)
    _GDIPlus_GraphicsDrawStringEx($backbuffer, $Progress & "%", $font, _GDIPlus_RectFCreate($width / 2 - 75, $height / 2 - 20, 150, 150), $sformat, $whitebrush)
    

    
    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height)
    Sleep(20)
Until False


Func pinger()
    If $PingsMade >= $PingsToMake Then Return
    $PingsMade += 1
    
    $randomhost = $Hosts[Random(0, UBound($Hosts) - 1, 1)]
    $res = Ping($randomhost, 250)
    If $res = 0 Then
        $TextQueue = $randomhost & " failed"
    Else
        $TextQueue = $randomhost & ": " & $res & " ms."
    EndIf
    

    
    $Progress = Round(($PingsMade / $PingsToMake) * 100)

EndFunc  ;==>pinger



Func close()
    Exit
EndFunc  ;==>close

...Yes I'm very bored...

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

Wow. I thank you all for your replies. I see from the dates/timestamps that you jumped in much more quickly than I had thought anyone would. I can see I'm going to learn a great deal in this forum. I appreciate the time spent and coding efforts. For my purposes, I ended up using a variant of martin's solution. But still thank you weaponX, Valuator, and monoceres, with a Golden Globe for Best Supporting Actor going to monoceres for the piechart ping. Quality!

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...