nill

Dont work StdoutRead with Putty.exe

28 posts in this topic

#1 ·  Posted (edited)

$user = "root"
$password =""
$host ="5.0.0.1"
$port ="22"

$puty_exe = @ScriptDir & "\putty.exe"; putty salve local folder script


$command = Run(@comspec & " /C "&$puty_exe&" -ssh -l "&$user&" "&$host&" p "&$port&" -pw "&$password,@ScriptDir, @SW_HIDE, 1)
While 1
$data = StdoutRead($command)
ConsoleWrite($data&@CRLF)
If @error Then ExitLoop
Wend

Why StdoutRead cant read what putty.exe write in console ?

Edited by nill

Share this post


Link to post
Share on other sites



Because you missed to set parameter opt_flag of the Run statement to $STDOUT_CHILD


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

 

2 hours ago, water said:

Because you missed to set parameter opt_flag of the Run statement to $STDOUT_CHILD

Please give me work example

I try many variants

Edited by nill

Share this post


Link to post
Share on other sites
21 minutes ago, nill said:

Please give me work example

I try many variants

The author of helpfile example to StdoutRead did this job already. Just look and adapt for your need.

Share this post


Link to post
Share on other sites
38 minutes ago, AutoBert said:

The author of helpfile example to StdoutRead did this job already. Just look and adapt for your need.

$command = Run(@comspec & " /C "&$puty_exe&" -ssh -l "&$user&" "&$host&" p "&$port&" -pw "&$password,@ScriptDir, @SW_HIDE, $STDOUT_CHILD)

dont help

where my mistake?

Share this post


Link to post
Share on other sites

Don't know if or where are your misatake(s). Run this script:

$user = "root"
$password = ""
$host = "5.0.0.1"
$port = "22"

$puty_exe = @ScriptDir & "\putty.exe"; putty salve local folder script
If Not FileExists($puty_exe) Then
    ConsoleWrite('putty not found' @CRLF)
    Exit
EndIf

$iPID = Run(@ComSpec & " /C " & $puty_exe & " -ssh -l " & $user & " " & $host & " p " & $port & " -pw " & $password, @ScriptDir@SW_MAXIMIZE, $STDERR_CHILD + $STDOUT_CHILD)
;change back to @SW_HIDE after script is successfully tested
$i = 0
While 1
    $sOutput = StdoutRead($iPID)
    If @error Then ; Exit the loop if the process closes or StdoutRead returns an error.
        ExitLoop
    EndIf
    ConsoleWrite("Stdout Read" & $i & ": " & $sOutput&@CRLF)
WEnd
$i = 0
While 1
    $i += 1
    $sOutput = StderrRead($iPID)
    If @error Then ; Exit the loop if the process closes or StderrRead returns an error.
        ExitLoop
    EndIf
    ConsoleWrite("Stderr Read" & $i & ": " & $sOutput&@CRLF)
WEnd
ConsoleWrite('Finished'&@CRLF)

and post output of the Sciteconsole.

Share this post


Link to post
Share on other sites

"I try many variants" and "don't help" aren't very informative. Please describe what's going wrong. What are (if any) your error messages? Does it work if you do it manually through the commandline?

One suggestion I would offer is to store the command you're executing in a temporary variable and writing it to the console (ConsoleWrite()) to see if you're actually executing the thing that you meant to execute.

Another suggestion, maybe that's the whole thing, is that the -p parameter for putty requires the dash, so change " p " & $port to " -p " & $port.


Roses are FF0000, violets are 0000FF... All my base are belong to you.

Share this post


Link to post
Share on other sites

AutoBert

you have erorr in code after i run your code i see this

$PID = Run(@ComSpec & " /C "&$puty_exe&" -ssh -l " & $user & " " & $host & " p " & $port & " -pw " & $password, @ScriptDir^ ERROR

but nothing change i cant read console in autoit

SadBunny

I dont have erorr massage but autoit nothing return in  StdoutRead after I run putty

with  dash  -p I have error

I run another program call vmrun.exe (from VMware) and I can read console

If you can just run putty.exe from autoit maybe I can see simple things

 

Share this post


Link to post
Share on other sites
1 hour ago, nill said:

you have erorr in code after i run your code i see this

sorry, i didn't test, please test this:

#include <AutoItConstants.au3>

$user = "root"
$password = ""
$host = "5.0.0.1"
$port = "22"

$puty_exe = @ScriptDir & "\putty.exe"; putty salve local folder script
If Not FileExists($puty_exe) Then
    ConsoleWrite('putty not found' &@CRLF)
    Exit
EndIf

$iPID = Run(@ComSpec & " /C " & $puty_exe & " -ssh -l " & $user & " " & $host & " p " & $port & " -pw " & $password, @ScriptDir,@SW_MAXIMIZE, $STDERR_CHILD + $STDOUT_CHILD)
;change back to @SW_HIDE after script is successfully tested
$i = 0
While 1
    $sOutput = StdoutRead($iPID)
    If @error Then ; Exit the loop if the process closes or StdoutRead returns an error.
        ExitLoop
    EndIf
    ConsoleWrite("Stdout Read" & $i & ": " & $sOutput&@CRLF)
WEnd
$i = 0
While 1
    $i += 1
    $sOutput = StderrRead($iPID)
    If @error Then ; Exit the loop if the process closes or StderrRead returns an error.
        ExitLoop
    EndIf
    ConsoleWrite("Stderr Read" & $i & ": " & $sOutput&@CRLF)
WEnd
ConsoleWrite('Finished'&@CRLF)

and please post console output after, mine output is:

>"C:\Program Files\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Users\Bert\AutoIt3.My\Test\test.au3" /UserParams    
+>23:58:54 Starting AutoIt3Wrapper v.14.801.2025.0 SciTE v.3.4.4.0   Keyboard:00000407  OS:WIN_81/  CPU:X64 OS:X64    Environment(Language:0407)
+>         SciTEDir => C:\Program Files\AutoIt3\SciTE   UserDir => C:\Users\Bert\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\Bert\AppData\Local\AutoIt v3\SciTE 
+>Check for missing standard constants/udf include files: 1 include(s) were added
>Running AU3Check (3.3.14.2)  from:C:\Program Files\AutoIt3  input:C:\Users\Bert\AutoIt3.My\Test\test.au3
+>23:58:57 AU3Check ended.rc:0
>Running:(3.3.14.2):C:\Program Files\AutoIt3\autoit3.exe "C:\Users\Bert\AutoIt3.My\Test\test.au3"    
--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
putty not found
+>23:58:57 AutoIt3.exe ended.rc:0
+>23:58:57 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 4.018

 

Share this post


Link to post
Share on other sites

AutoBert

in outputs i see this

>"C:\Program Files\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\Users\ADMIN\Desktop\putty\test_putty.au3"    
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 
Stdout Read0: 

 

many Stdout Read0:  script never end

Share this post


Link to post
Share on other sites

script end if I manually close console windows

Share this post


Link to post
Share on other sites

Try reading both the standard AND error streams and see if you get any?

 


Skysnake

Why is the snake in the sky?

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Use PLink. That's the command line tool for Putty. You'll find a lot of examples on the forum. 

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

@Jos, yes: Pscp and plink.  

3.7 The PuTTY command line

       PuTTY can be made to do various things without user intervention
       by supplying command-line arguments (e.g., from a command prompt
       window, or a Windows shortcut).

Look for the verbose mode. putty command line

GUI Putty should have a tick box for a log file. It may help to force putty into verbose mode.  See if you can log the output to a file.  Read the file afterwards.

 


Skysnake

Why is the snake in the sky?

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

It does not work with putty, only with plink. I've tried running it with putty for ages and failed. Since i don't have code in hand, i will describe how it works - open putty, save some session, then launch the plink proccess with the same session name. Write to sdin, wait some time , close proccess and then read stdout and stderr.

#include <constants.au3> ; not sure where was the child stuff stored
$somepid = run("c:\path\to\plink.exe -batch NameOfYourStoredConnection ","c:\path\to\", @sw_show $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
StdinWrite($somepid,"do stuff here")
sleep(100)
ProccessClose($somepid)
ProccessWaitClose($somepid)
$Output = StdoutRead($somepid)
$Error = StderrRead($somepid)
consolewrite("output - " & $Output & @CRLF)
consolewrite("error (if any) - " & $Error & @CRLF)
exit

Something like this (quick writed in box, hope you get the idea)

Edit : typos, i need english dictionary :D

Edited by JustSomeone

Share this post


Link to post
Share on other sites

water

JustSomeone

 

try to use plink.exe instead putty.exe

#include <AutoItConstants.au3>

$user = "root"
$password = "pass"
$host = "1.1.1.1"
$port = "22"

$puty_exe = @ScriptDir & "\plink.exe"; putty salve local folder script
If Not FileExists($puty_exe) Then
    ConsoleWrite('putty not found' &@CRLF)
    Exit
EndIf

$iPID = Run(@ComSpec & " /C " & $puty_exe & " -ssh -l " & $user & " " & $host & " p " & $port & " -pw " & $password, @ScriptDir,@SW_MAXIMIZE, $STDERR_CHILD + $STDOUT_CHILD)
;change back to @SW_HIDE after script is successfully tested
$i = 0
While 1
    $sOutput = StdoutRead($iPID)
    If @error Then ; Exit the loop if the process closes or StdoutRead returns an error.
        ExitLoop
    EndIf
    ConsoleWrite("Stdout Read" & $i & ": " & $sOutput&@CRLF)
WEnd
$i = 0
While 1
    $i += 1
    $sOutput = StderrRead($iPID)
    If @error Then ; Exit the loop if the process closes or StderrRead returns an error.
        ExitLoop
    EndIf
    ConsoleWrite("Stderr Read" & $i & ": " & $sOutput&@CRLF)
WEnd
ConsoleWrite('Finished'&@CRLF)

I get this text in autoit console

Stdout Read0: root@1.1.1.1's password: 

but why i cant login in on server ?

when I use this in putty.exe all is ok I login on server

when I mannually run plink.exe password requires too

 

I cant use StoredConnection like in JustSomeone example

Share this post


Link to post
Share on other sites

You are not having the correct parameter for port: change the " p " to " -P ".

$iPID = Run(@ComSpec & " /C " & $puty_exe & " " & $host & " -ssh -l " & $user & " -pw " & $password & " -P " & $port , @ScriptDir,@SW_MAXIMIZE, $STDERR_CHILD + $STDOUT_CHILD + $STDIN_CHILD )

Jos

1 person likes this

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
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

  • Similar Content

    • OGA
      By OGA
      Hi, I'm new.
      Anyways, I'm using the RunBinary.au3 script by trancexx and I want to re-direct the STDOUT of the "child process" back to the autoit script that launches it. I'm attempting to do so using named pipes. If its possible to use StdoutRead instead of namedpipes please let me know. I'm just unsure of how to provide a handle of the childs STDOUT stream to that function. Though DllCall("kernel32.dll", "ptr", "GetStdHandle", "dword", "STD_OUTPUT_HANDLE") seems to get the handle?
      Please excuse any foolish mistakes because I'm new to STDOUT, runbinary and namedpipes. Here's the parts of the code I'm trying to use that are relevent:
      ;~~~Firstly I think I need to make a pipe that's inheritable.. which I may have done wrong Local $_SECURITY_ATTRIBUTES = DllStructCreate("dword Length;" & _ "int lpSecurityDescriptor;" & _ "bool InheritHandle;") ;***Not positive if bool works correctly here? DLLStructSetData($_SECURITY_ATTRIBUTES, "Length", DllStructGetSize($_SECURITY_ATTRIBUTES)) DLLStructSetData($_SECURITY_ATTRIBUTES, "lpSecurityDescriptor", 0) ;***This sets default state; "If the value of this member is NULL, the object is assigned the default security descriptor associated with the access token of the calling process." but I'm unsure if this is what I should use DLLStructSetData($_SECURITY_ATTRIBUTES, "InheritHandle", true);***True = Inheritable(but again I'm not positive the bool works correctly?) Global $hNamedPipe = _NamedPipes_CreateNamedPipe("\\.\pipe\poopp", _;Name 2, _;Direction: 2=both ;I only need 1 direction but I'm just using this for testing 1, _;Flags: 1=no extra instances of pipe are allowed to run 0, _;Security: No ACL Security 0, _;Type: 0=byte 0, _;ReadType: 0=byte 1, _;Wait: 0=Block(wait) 1=No block(no wait) 1, _;Max Instances of pipe allowed 4096, _;out size 4096, _;in size 9000, _;timeout DllStructGetPtr($_SECURITY_ATTRIBUTES));Default=0 which wouldn't make the handle inheritable ;~~~Next I would need to set the STARTUPINFO of the process ;code used by trancexx for the _STARTUPINFO Global $tSTARTUPINFO = DllStructCreate("dword cbSize;" & _ "ptr Reserved;" & _ "ptr Desktop;" & _ "ptr Title;" & _ "dword X;" & _ "dword Y;" & _ "dword XSize;" & _ "dword YSize;" & _ "dword XCountChars;" & _ "dword YCountChars;" & _ "dword FillAttribute;" & _ "dword Flags;" & _ "word ShowWindow;" & _ "word Reserved2;" & _ "ptr Reserved2;" & _ "ptr hStdInput;" & _ "ptr hStdOutput;" & _ "ptr hStdError") ;Attempting to set the values for namedpipe redirection DllStructSetData($tSTARTUPINFO, "Flags", 0x00000100) ;***Flag = STARTF_USESTDHANDLES (I think I set it correctly?) DllStructSetData($tSTARTUPINFO, "hStdOutput", $hNamedPipe) ;***Currently setting the output handle to the SERVER end of the NamePipe I'm creating (which I'm pretty sure is wrong but idk how to use the Client End) ;~~~code used by trancexx for CreateProcess Global $aCall = DllCall("kernel32.dll", "bool", "CreateProcessW", _ "wstr", $sExeModule, _ "wstr", $sCommandLine, _ "ptr", 0, _ "ptr", 0, _ "bool", true, _ ;***changed to inherit handles (not positive I did so correctly) was int 0 before "dword", 4, _ ; CREATE_SUSPENDED ; <- this is essential "ptr", 0, _ "ptr", 0, _ "ptr", DllStructGetPtr($tSTARTUPINFO), _ "ptr", DllStructGetPtr($tPROCESS_INFORMATION)) ;~~~~~Code used in a loop to try to see if anything is being written into the pipe If _IsPressed(35, $hDLL) Then Local $pipeData = _NamedPipes_PeekNamedPipe($hNamedPipe) If @Error Then MsgBox(1,"PipeData Error",@Error & " | " & $pipeData) Else Local $r = _ArrayDisplay($pipeData) If @Error Then MsgBox(1,"Array Error",@Error & " | " & $pipeData) EndIf EndIf  
      I'm not using this exact code cause I changed it around some for the post. I'm mainly wondering how to correctly use the client end of the name pipe? I also had some values I wasn't sure if I set correctly because I don't have experience with com objects. And It seems the process launched needs to be the child?.. Can the process started through the autoitscript can be considered the child process and the script the parent process?
       
      Guides I'm using for this:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
      https://support.microsoft.com/en-us/help/190351/how-to-spawn-console-processes-with-redirected-standard-handles
    • careca
      By careca
      #include <Constants.au3> ListLetter() Func ListLetter() ;$DSK = Run("cmd", '', '', $STDIN_CHILD + $STDOUT_CHILD) $DSK = Run(@ComSpec & " /c diskpart.exe start", '', '', $STDIN_CHILD + $STDOUT_CHILD) ConsoleWrite('$DSK - '& $DSK&' - Error - '& @error &' - '&@MSEC&@CRLF) Sleep(2000) $Read = StdoutRead($DSK, True, False) ConsoleWrite(' - '& @error &' - '&@MSEC&@CRLF) ConsoleWrite('StdoutRead ' &$Read&' - '&@MSEC&@CRLF) EndFunc ;==>ListLetter So, this works with normal console "cmd" why does it error with diskpart? how can i make it read from diskpart?
    • dubi
      By dubi
      Hi,


       
      Background: i have a number of instances of the same application that I want to automate in parallel.

      Unfortunately, I cannot completely automate these instances in the background. So, from time to time these instances need to have the focus so that I can interact with the controls via “send” directly.

      Each of the application instances is controlled by a au3 complied script. Each script (called with a parameter) manages the automation of the respective application-instance. Each of the (complied) script (instances) is called by a (central) front end with a gui. The front end controls if the “focus” is available to do the “send” and “mouseclick” modifications. The central front end either allows a child to have the focus or prevents it to get the focus (in which case the child will wait and checks again). The code for the front end is included. Apologies for the lengthy explanation.


      #RequireAdmin #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> #include <GUIEdit.au3> #include <ScrollBarConstants.au3> #include <Array.au3> Global Const $APF_ALLOWMULTILINE = 1 Global Const $APF_RIGHTALIGN = 6 Global Const $APF_RIGHTALIGNCOL = 2 Global Const $APF_RIGHTALIGNDATA = 4 Global Const $APF_PRINTROWNUM = 8 Global Const $APF_DEFAULT = $APF_PRINTROWNUM Global $PID[9], $FocusAvailable = True, $previousEditMsg Global $PID_waiting[0][2], $logfile $logfile = "D:\MultiInstance\Logfiles\FrontEnd.txt" If FileExists($logfile) Then FileDelete($logfile) #Region ### START Koda GUI section ### Form= $hGui_1 = GUICreate("Instanzenmanager", 493, 1226, 1807, 93) $grpInst1 = GUICtrlCreateGroup(" 1 ", 8, 8, 233, 121) $btnPause01 = GUICtrlCreateCheckbox("Pause", 16, 64, 50, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $tbnStop01 = GUICtrlCreateCheckbox("Stop", 16, 96, 218, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnMin01 = GUICtrlCreateCheckbox("Minimize", 72, 64, 66, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnWdh01 = GUICtrlCreateCheckbox("Restore", 144, 64, 90, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnStart01 = GUICtrlCreateCheckbox("Start", 16, 32, 218, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) GUICtrlSetBkColor(-1, 0x00FF00) GUICtrlCreateGroup("", -99, -99, 1, 1) $grpInst3 = GUICtrlCreateGroup(" 3 ", 8, 136, 233, 121) $btnPause03 = GUICtrlCreateCheckbox("Pause", 16, 192, 50, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $tbnStop03 = GUICtrlCreateCheckbox("Stop", 16, 224, 218, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnMin03 = GUICtrlCreateCheckbox("Minimize", 72, 192, 66, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnWdh03 = GUICtrlCreateCheckbox("Restore", 144, 192, 90, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnStart03 = GUICtrlCreateCheckbox("Start", 16, 160, 218, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) GUICtrlSetBkColor(-1, 0x00FF00) GUICtrlCreateGroup("", -99, -99, 1, 1) $grpInst2 = GUICtrlCreateGroup(" 2 ", 248, 8, 233, 121) $btnPause02 = GUICtrlCreateCheckbox("Pause", 256, 64, 50, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $tbnStop02 = GUICtrlCreateCheckbox("Stop", 256, 96, 218, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnMin02 = GUICtrlCreateCheckbox("Minimize", 312, 64, 66, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnWdh02 = GUICtrlCreateCheckbox("Restore", 384, 64, 90, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnStart02 = GUICtrlCreateCheckbox("Start", 256, 32, 218, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) GUICtrlSetBkColor(-1, 0x00FF00) GUICtrlCreateGroup("", -99, -99, 1, 1) $grpInst4 = GUICtrlCreateGroup(" 4 ", 248, 136, 233, 121) $btnPause04 = GUICtrlCreateCheckbox("Pause", 256, 192, 50, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $tbnStop04 = GUICtrlCreateCheckbox("Stop", 256, 224, 218, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnMin04 = GUICtrlCreateCheckbox("Minimize", 312, 192, 66, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnWdh04 = GUICtrlCreateCheckbox("Restore", 384, 192, 90, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnStart04 = GUICtrlCreateCheckbox("Start", 256, 160, 218, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) GUICtrlSetBkColor(-1, 0x00FF00) $Edit1 = GUICtrlCreateEdit("", 8, 720, 473, 497) $btnPauseAll = GUICtrlCreateCheckbox("Pause all", 8, 656, 474, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) $btnStopAll = GUICtrlCreateCheckbox("Stop all", 7, 688, 474, 25, BitOR($GUI_SS_DEFAULT_CHECKBOX, $BS_PUSHLIKE)) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 CheckGuiMsg() FileWrite($logfile, @HOUR & ":" & @MIN & ":" & @SEC & "> " & "CheckGuiMsg" & @CRLF) CheckClientMessages() FileWrite($logfile, @HOUR & ":" & @MIN & ":" & @SEC & "> " & "CheckClientMessages" & @CRLF) WEnd Func CheckGuiMsg() $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $btnStart01 AddTextToEdit("Starting Instance 1") $PID[0] = Run("D:\XVM05\Entwicklung_FilterTest_Multi_ToFileV001.exe 1", @ScriptDir, Default, 3) Case $btnStart02 AddTextToEdit("Starting Instance 2") $PID[1] = Run("D:\XVM05\Entwicklung_FilterTest_Multi_ToFileV001.exe 2", @ScriptDir, Default, 3) Case $btnStart03 AddTextToEdit("Starting Instance 3") $PID[2] = Run("D:\XVM05\Entwicklung_FilterTest_Multi_ToFileV001.exe 3", @ScriptDir, Default, 3) Case $btnStart04 AddTextToEdit("Starting Instance 4") $PID[3] = Run("D:\XVM05\Entwicklung_FilterTest_Multi_ToFileV001.exe 4", @ScriptDir, Default, 3) Case $btnPause01 AddTextToEdit("Send Pause to Instance 1") StdinWrite($PID[0], "Pause") Case $btnPause02 StdinWrite($PID[1], "Pause") Case $btnPause03 StdinWrite($PID[2], "Pause") Case $btnPause04 StdinWrite($PID[3], "Pause") Case $tbnStop01 StdinWrite($PID[0], "Stop") Case $tbnStop02 StdinWrite($PID[1], "Stop") Case $tbnStop03 StdinWrite($PID[2], "Stop") Case $tbnStop04 StdinWrite($PID[3], "Stop") Case $btnPauseAll AddTextToEdit(@CRLF & "************Pause All not yet implemented**************" & @CRLF) Case $btnStopAll AddTextToEdit(@CRLF & "************Stop All not yet implemented***************" & @CRLF) EndSwitch EndFunc ;==>CheckGuiMsg Func CheckClientMessages() For $i = 0 To 3 FileWrite($logfile, @HOUR & ":" & @MIN & ":" & @SEC & "> " & $i & @CRLF) Local $a = TimerInit() $p = $PID[$i] $streamRead = StdoutRead($p) If $streamRead <> "" Then Switch $streamRead Case StringInStr($streamRead, "Focus Needed") > 0 If $FocusAvailable Then $FocusAvailable = False StdinWrite($p, "Focus Granted") Else EndIf Case StringInStr($streamRead, "Release Focus") > 0 StdinWrite($p, "Release Focus Received") $FocusAvailable = True Case Else EndSwitch EndIf FileWrite($logfile, @HOUR & ":" & @MIN & ":" & @SEC & "> " & $i & " " & round(TimerDiff($a),2) & @CRLF) Next EndFunc ;==>CheckClientMessages Func AddTextToEdit($text) If $previousEditMsg <> $text Then $previousEditMsg = $text GUICtrlSetData($Edit1, GUICtrlRead($Edit1) & @YEAR & "." & @MON & "." & @MDAY & " - " & @HOUR & ":" & @MIN & ":" & @SEC & "> " & $text & @CRLF) _GUICtrlEdit_Scroll($Edit1, $SB_SCROLLCARET) EndIf EndFunc ;==>AddTextToEdit



      My issue now is that the mechanism with with StdoutRead and StdinWrite is not efficient at all. The more instances I start the slower it gets. This is not just a bit slower (like a fraction of a second), but to the degree that the front end is not responding at all any longer (with 3 instances handling).

      So my questions are:

      1.       Is there a flaw in my implementation with StdoutRead and StdinWrite? (note that all works fine with 1 and also (slower) with 2 instances running) but actually breaks down with 3 instances running.

      2.       Can I optimize the currently used implementation so that I can control 30+ instances?

      3.       What other implementation do you see suitable for this approach?

      a.       I have already tried it with communication through files but observed that this is not sufficiently reliable with multiple instances.

      b.       Is Named Pipes a more performant approach (I am a bit scared of the effort to learn and implement this)

      c.       Any other method?


       
      Many thanks in advance

      -dubi





    • Skysnake
      By Skysnake
      Perhaps someone would benefit off this.  I made heavy use of the Help file example.
      Only question I have here, is is there a better way to do the Regex for finding "error|ERROR|Error" in the source string?  Thx
      Example7zPwd() Func Example7zPwd() ;-- Local $iPID = Run(@ComSpec & " /c DIR Example.au3", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Local $iPID = Run(@ComSpec & " /c 7za t -pmasale myzip.zip ", "c:\files\testing", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Local $sOutput = "" Local $myError = 0 ConsoleWrite("$myError:" & $myError & @CRLF) While 1 $sOutput = StdoutRead($iPID) If @error Then ; Exit the loop if the process closes or StdoutRead returns an error. ExitLoop EndIf MsgBox($MB_SYSTEMMODAL, "Stdout Read:", $sOutput, 5) If StringRegExp($sOutput, '\b(error|ERROR|[Ee]rror)\b', 0) Then $myError = $myError + 1 ;ConsoleWrite("$sOutput: " & $sOutput & @CRLF) ConsoleWrite("$myError: " & $myError & @CRLF) WEnd While 1 $sOutput = StderrRead($iPID) If @error Then ; Exit the loop if the process closes or StderrRead returns an error. ExitLoop EndIf MsgBox($MB_SYSTEMMODAL, "Stderr Read:", $sOutput, 15) WEnd ConsoleWrite("$myError: " & $myError & @CRLF) If $myError > 0 Then MsgBox(64, "An Error Occurred", "The upgrade may be incomplete. An error occurred") EndIf If StringRegExp($sOutput, '\b(error|ERROR|[Ee]rror)\b', 0) Then Is the Regex here optimized?
       
       
    • mojomatt
      By mojomatt
      Question regarding StdinWrite  and Stdoutread…
      Here’s my setup…
      I’m opening a powershell session using the AutoIT Run function with the $STDIN_CHILD  and $STDOUT_CHILD optional flags.
      I’m then sending a command using the STDINWRITE function to connect to a remote server which is a long distance away and it takes a “long” time to return results.
      I’m then trying to read the STDOUT stream.
      After this there are other STDINWRITE statements that I need to make so the STREAM hasn’t closed at this point.
      My question is this…How do I know for sure when all the data has been returned from the remote server after my first STDINWRITE?
      Things I’ve tried and don’t work…
      Use a loop which waits for @error to be non-zero.  This doesn’t work because as long as the STREAM is open then @error never is set to non-zero.
      Use a loop which waits for @extended to be 0.  This doesn’t work because the remote server sends data back in bursts and I don’t know how much time will pass in-between bursts.
      The only thing that is somewhat reliable is utilizing very long sleep statements – like 5 minutes – which really slows down my script and doesn’t ensure success either.
      What I really need is a way to tell that control has been returned to the command prompt.  What I mean by this is if you open a command prompt and issue the command DIR C:\ /s which lists all the files and folders on your C: drive you know you can’t issue any more commands until you get a blinking cursor at the command prompt again.  How do I programatically know when I get a blinking cursor again?
      Sample code that isn’t 100% foolproof…
      This code uses the logic looking for an @error to be non-zero...
      #include <constants.au3> Dim $StrOutput $StrPowerShellPID = Run('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe  -command - ',@SystemDir, @SW_HIDE, $STDIN_CHILD + $STDERR_MERGED) StdinWrite($StrPowerShellPID, "Dir C:\" & @CRLF) ;this is just an example command ; I can't close the STDOUT stream at this point because I need to issue additional commands into the existing STDIN stream later in the script While 1 ;Wait for EOF as indicated by @error being non-zero     $StrOutput &= StdoutRead($StrPowerShellPID)     If @error <> 0 Then ExitLoop     sleep (500) WEnd Consolewrite($StrOutput) The above code doesn't work because @error will never be set to non-zero since the stream isn't closed.  I can't close the stream because I need to issue additional commands into it.
       
       
      This code uses logic looking for an @extended value of 0 indicating no data was returned to the stream...
      #include <constants.au3> Dim $StrOutput $StrPowerShellPID = Run('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command - ',@SystemDir, @SW_HIDE, $STDIN_CHILD + $STDERR_MERGED) StdinWrite($StrPowerShellPID, "Dir ""C:\program files\common files"" -recurse" & @CRLF) While 1 ;This loop detects when data starts to stream in and then exits the loop $StrOutput &= StdoutRead($StrPowerShellPID) If @extended > 0 Then ExitLoop sleep(1000) WEnd While 1 ;Now that data has begun to stream in I wait until I can't read any more data as indicated by 0 bytes read in the value of @extended $StrOutput &= StdoutRead($StrPowerShellPID) If @extended = 0 Then ExitLoop ;~ sleep (1000) ; this is the only way to get this specific sample to work but this won't work for me because I don't know the time in-between bursts of data coming into the STDIN stream WEnd ConsoleWrite($StrOutput) ;If you look at the output you'll see it's not complete because @extended was set to 0 during the second loop The above code doesn't always work because if the remote server doesn't send any data for several seconds, then the StdoutRead thinks it's done reading when in reality it may not be.