sliceofpie Posted February 15, 2011 Share Posted February 15, 2011 Hi, Is there a way to display the results of a running command, such as ping, and then display those in an AutoIt GUI window? What I'm trying to do is have a task scheduled "ping.exe 4.2.2.2 | ConsoleRead.exe". The ConsoleRead.exe will either send the information to my running script or write to a file that my script reads and displays each line item one by one. Any help is greatly appreciated. Thanks! Link to comment Share on other sites More sharing options...
sliceofpie Posted February 15, 2011 Author Share Posted February 15, 2011 (edited) Here's my current attempt. ConsoleRead.exe compiled (code mainly taken from the help file) Local $data While True $data = ConsoleRead() If @error Then ExitLoop IniWrite(@ScriptDir & "\ping.ini", "results", "reply", $data) Sleep(1000) WEnd My Script expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= Opt( "TrayMenuMode" , 1) $exititem = TrayCreateItem("Force Quit") $Form1 = GUICreate("Form1", 554, 53, 58, 186) $sLine = "Start" $BackupItems = GUICtrlCreateLabel($sLine, 8, 16, 529, 21) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### ;run(@ComSpec & " /c " & @ScriptDir & "\ping 4.2.2.2 | ConsoleRead.exe") _ReadLines() While 1 Switch TrayGetMsg() Case 0 ContinueLoop Case $exititem ExitLoop EndSwitch WEnd Func _ReadLines() Sleep (1000) While 1 $Results = IniRead("ping.ini", "results", "reply", "") GUICtrlSetData ($BackupItems, $Results) ConsoleWrite($Results) WEnd EndFunc So I have 2 issues.. 1. The .ini file that gets created by ConsoleRead.exe is not pretty 2. The GUI displays the first line from ping.ini over and over again. I'm not sure if this is the best way of doing this. Again.. any help is greatly appreciated. Edited February 16, 2011 by sliceofpie Link to comment Share on other sites More sharing options...
JoHanatCent Posted February 16, 2011 Share Posted February 16, 2011 So I have 2 issues.. 1. The .ini file that gets created by ConsoleRead.exe is not pretty 2. The GUI displays the first line from ping.ini over and over again. I'm not sure if this is the best way of doing this. Again.. any help is greatly appreciated. 1. Do you have to write this to a .ini? Why not read it traight ofF? 2. You only need to update the label every time it have to change. See if this example could help: #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("TrayMenuMode", 1) $exititem = TrayCreateItem("Force Quit") $Form1 = GUICreate("Form1", 554, 53, 58, 186) $sLine = "Start" $BackupItems = GUICtrlCreateLabel($sLine, 8, 16, 529, 21) GUISetState(@SW_SHOW) $Results = $sLine While 1 $Results = Ping("196.31.6.22", 250);<< Can also read cmd results with StdoutRead ;<< $pid = run(@ComSpec & " /c " & @ScriptDir & "\ping 4.2.2.2 ","", @SW_HIDE, 2 + 4) Switch TrayGetMsg() Case 0 ContinueLoop Case $exititem ExitLoop EndSwitch If $Results <> $sLine Then;<< Only updates when it changes GUICtrlSetData($BackupItems, $Results) ConsoleWrite($Results & @CRLF) $sLine = $Results EndIf Sleep(50) WEnd Link to comment Share on other sites More sharing options...
sliceofpie Posted February 16, 2011 Author Share Posted February 16, 2011 (edited) Thanks for the example. I've been working with it and I like how it only updates it when the results change. I also didn't know that AutoIt had a ping command built-in. You made a comment that this can also be accomplished using StdoutRead.. How is this possible? I have a batch file in scheduled task that kicks off "ping.exe 4.2.2.2" so my script doesn't start the command line app. I looked at this before but since AutoIt doesn't start it, I thought I couldn't use StdoutRead. Therefore I thought ConsoleRead would work. How do I read the output of a command line app such as ping.exe if it's not run by my script? Edited February 16, 2011 by sliceofpie Link to comment Share on other sites More sharing options...
Xenobiologist Posted February 16, 2011 Share Posted February 16, 2011 Hi, try this: ConsoleWrite( _getDOSOutput('ping 4.2.2.2') & @CRLF) Func _getDOSOutput($command) Local $text = '', $Pid = Run('"' & @ComSpec & '" /c ' & $command, '', @SW_HIDE, 2 + 4) While 1 $text &= StdoutRead($Pid, False, False) If @error Then ExitLoop Sleep(10) WEnd Return $text EndFunc ;==>_getDOSOutput Mega Scripts & functions Organize Includes Let Scite organize the include files Yahtzee The game "Yahtzee" (Kniffel, DiceLion) LoginWrapper Secure scripts by adding a query (authentication) _RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...) Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc. MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times Link to comment Share on other sites More sharing options...
JoHanatCent Posted February 16, 2011 Share Posted February 16, 2011 expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Constants.au3> Opt("TrayMenuMode", 1) $exititem = TrayCreateItem("Force Quit") $Form1 = GUICreate("Form1", 554, 53, 58, 186) $sLine = "Start" $BackupItems = GUICtrlCreateLabel($sLine, 8, 16, 529, 21) GUISetState(@SW_SHOW) $Results = $sLine $Command = "Ping 4.2.2.2 -t" Local $Run = Run(@ComSpec & " /c " & $Command, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) If $Run = 0 Then MsgBox(0, "", "UnAble to run your command", 5) Exit EndIf While 1 $Results = StdoutRead($Run) If $Results = "" Then $Results = $sLine;<< Get rid of blank responses $msg = TrayGetMsg() Select Case $msg = 0 ContinueLoop Case $msg = $exititem ExitLoop EndSelect If $Results <> $sLine Then;<< Only updates when it changes GUICtrlSetData($BackupItems, $Results) ConsoleWrite($Results & @CRLF) $sLine = $Results EndIf Sleep(10) If @error Then ExitLoop WEnd ProcessClose("cmd.exe") Exit Link to comment Share on other sites More sharing options...
sliceofpie Posted February 16, 2011 Author Share Posted February 16, 2011 (edited) Xenobiologist / JoHanatCent,Thank you both for your feedback. Your examples assume that the command line is a child process. As I stated before, AutoIt does not RUN the process, it gets started outside of my script. Maybe WM_COPYDATA is a better way of doing it? I checked out this post http://www.autoitscript.com/forum/index.php?showtopic=77979 and got some ideas..So the way I have it setup is:1. A scheduled task runs "ping.exe 4.2.2.2 | ConsoleRead.exe" every hour.2. ConsoleRead.exe (see below) reads the information and sends it to my script#include "MessageHandler.au3" $Local_ReceiverID_Name = "Script1sReceiverID";This is the ID that the other script will use to send data $Remote_ReceiverID_Name = "Script2sReceiverID";This is the ID of the script we want to send data too $hwnd = _SetAsReceiver($Local_ReceiverID_Name) Local $data While True $data = ConsoleRead() $iSent = _SendData($data,$Remote_ReceiverID_Name) If @error Then ExitLoop Sleep(25) WEnd 3. My script displays the output using GUICtrlCreateLabel and GUICtrlSetDataexpandcollapse popup#include "MessageHandler.au3" #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= Opt( "TrayMenuMode" , 1) $exititem = TrayCreateItem("Force Quit") $Form1 = GUICreate("Form1", 554, 53, 58, 186) $sLine = "start" $BackupItems = GUICtrlCreateLabel($sLine, 8, 16, 529, 21) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### $Local_ReceiverID_Name = "Script2sReceiverID";This is the ID that the other script will use to send data $Remote_ReceiverID_Name = "Script1sReceiverID";This is the ID of the script we want to send data too $hwnd = _SetAsReceiver($Local_ReceiverID_Name) ConsoleWrite("hwnd of the Local_ReceiverID_Name is " & $hwnd & @crlf) $myFunc = _SetReceiverFunction("_MyFunc2") ConsoleWrite("My data receiver function is " & $myFunc & @crlf) While 1 ;Sleep(10) ;If TrayGetMsg() = "Exit" Then Exit Switch TrayGetMsg() ;switch seems nicer in this case Case 0 ContinueLoop Case $exititem ExitLoop EndSwitch WEnd Func _MyFunc2($vText) While 1 If $vText = "" Then $vText = $sLine If $vText <> $sLine Then;<< Only updates when it changes GUICtrlSetData($BackupItems, $vText) ConsoleWrite($vText & @CRLF) $sLine = $vText EndIf Sleep(10) If @error Then ExitLoop WEnd EndFuncThe only problem I have that it CRASHES now when my script receives the output from ConsoleRead.exe.Sorry for going a different direction with this. Because of the way the command gets run I thought of using wm_copydata. Edited February 16, 2011 by sliceofpie Link to comment Share on other sites More sharing options...
sliceofpie Posted February 17, 2011 Author Share Posted February 17, 2011 anyone? Link to comment Share on other sites More sharing options...
sliceofpie Posted February 18, 2011 Author Share Posted February 18, 2011 I think I figured it out.. ConsoleRead.exe #include <WindowsConstants.au3> #include "MessageHandler.au3" $Local_ReceiverID_Name = "Script1sReceiverID" $Remote_ReceiverID_Name = "Script2sReceiverIDp" Local $Data While True $Data = ConsoleRead() If @error Then ExitLoop $iSent = _SendData($Data,$Remote_ReceiverID_Name) Sleep (75) WEnd Exit My script expandcollapse popup#include <WindowsConstants.au3> #include "MessageHandler.au3" Global $hParent, $hwnd, $received $Local_ReceiverID_Name = "Script2sReceiverID" $Remote_ReceiverID_Name = "Script1sReceiverID" $Form1 = GUICreate("Form1", 554, 53, 58, 186) $sLine = "start" $input_received = GUICtrlCreateLabel($sLine, 8, 16, 529, 21) GUISetState(@SW_SHOW) $hwnd = _SetAsReceiver($Local_ReceiverID_Name) GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA_ReceiveData") ; register WM_COPYDATA While Not $received ; wait for child process to return it's handle Sleep(50) WEnd $hwnd = HWnd($received); assign child hamdle $received = "" ; main loop While 1 $msg = GUIGetMsg() If $msg = -3 Then ExitLoop If $received Then GUICtrlSetData($input_received, $received) ; receive form child $received = "" EndIf WEnd Exit ;=================================================================================================================================== Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ; Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam) Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3)) $received = DllStructGetData($tMsg, 1) EndFunc Sometimes it helps just contacting the forums to get fresh ideas Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now