Jump to content
Sign in to follow this  
corgano

Reading STDout of running process

Recommended Posts

corgano

How do you read the STDout stream from an already running process? I know you can launch a program via run() with flags to get the SDTout stream, but being able to change and re-run a script without needing to restart the running process would be very useful

In this thread, it is suggested that one could use the GetStartupInfo methiod, but I'm not sure how to call it or what dll it's in

'?do=embed' frameborder='0' data-embedContent>>

Edit: Here is my attempt at changing it to autoit. I'm confused as to how you're supposed to specify what process you're trying to get the stream of, and am probably doing it wrong.

$STARTUPINFO=DllStructCreate("" & _
  "DWORD  cb;" & _
  "ptr lpReserved;" & _
  "ptr lpDesktop;" & _
  "ptr lpTitle;" & _
  "DWORD  dwX;" & _
  "DWORD  dwY;" & _
  "DWORD  dwXSize;" & _
  "DWORD  dwYSize;" & _
  "DWORD  dwXCountChars;" & _
  "DWORD  dwYCountChars;" & _
  "DWORD  dwFillAttribute;" & _
  "DWORD  dwFlags;" & _
  "USHORT   wShowWindow;" & _
  "USHORT   cbReserved2;" & _
  "ptr lpReserved2;" & _
  "HANDLE hStdInput;" & _
  "HANDLE hStdOutput;" & _
  "HANDLE hStdError;")


DllCall("Kernel32.dll","none","GetStartupInfo","ptr",DllStructGetPtr($STARTUPINFO))
$handle = DllStructGetData($STARTUPINFO,"hStdOutput")
#include <Constants.au3>

Local $line
While 1
    $line = StdoutRead($handle)
    If @error Then ExitLoop
    if StringLen($line) > 3 Then ConsoleWrite($line)
WEnd 

I appreciate any help

Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Share this post


Link to post
Share on other sites
corgano

Bump? Is there something obvious that I'm missing here or does no one really know? Is it impossible to do with AutoIt?

One thing I'm considering is having a helper script that works between the program and my program, that will detect when my main script starts and redirect the console information to it . This seems like a really awkward and roundabout way of doing things... 

I Have a completed example here

Helper.au3 (compile before use)

#include <Constants.au3>

AutoItWinSetTitle("Helper") ;used for the main script to detect it

$MainPID = ""


While Sleep(1000)   ;while running (add exit conditions in this loop)

    If WinExists("Mainscript|") Then    ;Detect the main script starting. This will only happen if it was started with no cmdline

        ;get the path (as part of it's title) of the mainscript and close it
        $title = WinGetTitle("Mainscript|")
        ProcessClose(WinGetProcess($title))

        ;get the path of the main script
        $mainPath = StringReplace($title, "Mainscript|", "")
        $mainDir = StringLeft($mainPath, StringInStr($mainPath, "\", 0, -1))
        If StringRight($mainPath, 4) = ".au3" Then $mainPath ='"C:\Program Files (x86)\AutoIt3\AutoIt3.exe" "'&$mainPath&'"'

        ;run the main script again, this time as child so we can send it console info
        $MainPID = Run($mainPath&" "&@AutoItPID, $mainDir, Default, $STDIN_CHILD + $STDOUT_CHILD)

        While ProcessExists($MainPID)
            Sleep(1000)

            ;code to get useful data here
            StdinWrite($MainPID, "From helper:  "&Random(0,9999999,1) & @CRLF)
            If @error Then
                StdinWrite($MainPID)
                ExitLoop
            EndIf

        WEnd

    EndIf

WEnd

and the main script

#include <GuiRichEdit.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

;when the helper runs it then it's run with the helper's PID
if $CmdLine[0] = 0 Then ;when run by itself

    AutoItWinSetTitle("Mainscript|"&@ScriptFullPath)    ;the helper looks for this, and gets the script path from this

    If not WinExists("Helper") Then
        ConsoleWrite("Starting helper..."&@CRLF)
        Run("helper.exe")
    Else
        ConsoleWrite("Waiting for helper"&@CRLF)
    EndIf

    while sleep(100)    ;wait for the helper to close it. When the helper
    WEnd

EndIf

;if the helper launches it

Local $hGui, $hRichEdit, $iMsg
$hGui = GUICreate("Example (" & StringTrimRight(@ScriptName, 4) & ")", 320, 350, -1, -1)
$hRichEdit = _GUICtrlRichEdit_Create($hGui, "Command line: "&$CmdLineRaw&@CRLF, 10, 10, 300, 220, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
GUISetState()


While True

    $line = ConsoleRead()
    if StringLen($line) > 3 Then
        _GUICtrlRichEdit_AppendText($hRichEdit, $line)
    EndIf


    $iMsg = GUIGetMsg()
    Select
        Case $iMsg = $GUI_EVENT_CLOSE
            _GUICtrlRichEdit_Destroy($hRichEdit) ; needed unless script crashes
            GUIDelete()     ; is OK too
            Exit
    EndSelect
WEnd

The main script can be either au3 OR exe and the helper can find and send data to it. To test:

Run helper.exe

Run the source from SciTE, Observe it working

Close it. Leave the helper running

Compile the main script, and run main.exe

Helper will see it and attach to it. Observe it working

Probably nto the best way to do it, but works. Anyone got a better way 


0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

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
Sign in to follow this  

  • Similar Content

    • TryWare90Days
      By TryWare90Days
      I'm trying to kill a malware process, that I can't remove with my www.sophus.com/hom antivirus.

      The malware is known as coinminer,config and my Sophus only creates popups of blocking the malware.

      I know that the malware is constantly launching a svchost *32.exe processes, where the svchost.exe processes are from my Windows 7 operating system.
      I have with no luck tried to do this:
      Global $_bStatus = False
      While $_bStatus = False
                 Global $_iPid
                 Global $_sActiveTitleNew = "svchost *32.exe"
                 $_iPid = WinGetProcess($_sActiveTitleNew)
                 If $_iPid <> -1 Then $_bStatus = ProcessClose($_iPid)   
      Wend
      EXIT
       
      But the $_iPid doesn't ever show anything else than  -1, even if I can see the svchost *32.exe process in my TaskManager
       
      YES - I know I shouldn't EXIT after killing the first malware detection, but it is easier to explain the above for you, so I can get a solution.
    • boomingranny
      By boomingranny
      Use this UDF to add a console gui to your script (with log file):
      It uses the Hidden Autoit window (that you probably didn't even know existed)
      Closing Console window will terminate script.
      example of console:

      #include-once #include <GuiEdit.au3> EnableConsoleGui("example.log") ;example: ;------------------------ ConsoleWrite ("Hello World") For $i = 1 To 10 ConsoleWrite (".") Sleep(200) Next ConsoleWrite ("done") ConsoleWrite(@CRLF) ConsoleWrite ("close me to exit"&@CRLF) While 1 Sleep(1000) WEnd ;------------------------ ;end of example code Func EnableConsoleGui($Logfile="") ;EnableConsoleGUI ;by Daniel Barnes 20/04/2018 ;Uses AutoIt's Hidden window as a console (output only) Global $pidChild ;if we don't have a parent (as the parent window would have our script name) If Not WinExists(StringTrimRight(@ScriptName,4)) Then Opt("TrayIconHide",1) ;get Autoit's hidden window handle local $hWnd = WinGetHandle(AutoItWinGetTitle()) ;move the autoit hidden window to the middle of the screen WinMove($hWnd, "", (@DesktopWidth / 2) - 250, (@DesktopHeight / 2) - 250, 500, 500) ;get the Handle of the edit box in Autoit's hidden window $hEditBox = ControlGetHandle($hWnd,"","[CLASS:Edit; INSTANCE:1]") ;show it WinSetState($hWnd, "", @SW_SHOW) ;set its title = our script name WinSetTitle($hWnd,"",StringTrimRight(@ScriptName,4)) ;Spawn a child "copy" of the script, enabling reading of its console... If @Compiled Then ;2 = $STDOUT_CHILD. This avoids requiring the AutoItConstants.au3 in this sample code $pidChild= Run( FileGetShortName(@ScriptFullPath),@ScriptDir,"",2) Else ;2 = $STDOUT_CHILD. This avoids requiring the AutoItConstants.au3 in this sample code $pidChild= Run( FileGetShortName(@AutoItExe) & " " & FileGetShortName(@ScriptFullPath),@ScriptDir,"",2) EndIf OnAutoItExitRegister("EnableConsoleGui_CloseChildPID") ;read the console, while the child window exists (and the console window is visible) While ProcessExists($pidChild) $ConsoleRead = StdoutRead($pidChild) If $ConsoleRead then $text = StringLeft(ControlGetText($hWnd,"",$hEditBox),65535) If $Logfile Then FileWrite($Logfile,$ConsoleRead) $text &= $ConsoleRead ControlSetText($hWnd,"",$hEditBox,$text) ConsoleWrite($ConsoleRead) ;scroll to bottom of console edit window _GUICtrlEdit_SetSel($hEditBox, 65535, 65535) endif Sleep(250) WEnd exit endif EndFunc Func EnableConsoleGui_CloseChildPID() ;if this func isn't used ;when you close the console gui ;the child "clone" of your script will keep running ProcessClose($pidChild) EndFunc
    • nacerbaaziz
      By nacerbaaziz
      Hello my friends
      I have an inquiry after your permission
      I found a function to get the special line commands for any operation
      It requires the name of the process to be searched
      I want to use it to know the process
      Is this possible with this function
      Here is the code
       
      Func commandLineGet($proc, $strComputer=".")
      dim $array[1]
      local $ArrayNumber
      local $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
      local $oProcessColl = $oWMI.ExecQuery("Select * from Win32_Process where Name= " & '"'& $Proc & '"')
      local $Process
      For $Process In $oProcessColl
      $Process = $Process.Commandline
          ReDim $Array[UBound($Array)+1]
      $ArrayNumber = UBound($Array)-1
      $array[$ArrayNumber] = $Process
      Next
      $ArrayNumber = UBound($Array)-1
      $array[0] = $ArrayNumber
      return $array
      EndFunc
    • simy8891
      By simy8891
      Hi guys,
      It's been a while since I wrote my last message here and a while since I used AutoIt. I'm currently sort of desperate and I'm trying to find some help in regards of getting the network usage per process!
      I'm not interested in the total network usage of the NIC, but only on a specific PID's network utilization. They idea is to collect the amount of traffic uploaded and downloaded by a list of specific processes. So far Process Hacker and Process Explorer are capable of getting what I need, but I need to use these numbers in another script so they're sort of useless to me. I can't seem to find a way around it.
      Any idea, help is greatly appreciated.
      Thanks
    • Kevin Finnegan
      By Kevin Finnegan
      Hi all,
      Long time lurker and now forum poster! I'm writing a relatively simple backup script for my firm that automates the copy, compression and organization of Leaver's data on one of our secured NAS systems. I personally found the best method to do this so far was to use 7zG.exe (GUI version of 7Zip which can use command-line too) and it functions quite well!
      I would like to retrieve more info on whether any warnings or errors happen in 7Zip during the backup, but I can't quite get my head around the syntax and switches for reading out, it seems any adjustment I make to the RunWait call's string seems to break the backup or give unexpected repercussions! Hopefully its something silly I'm doing as I don't code very often.
      Here is the working version:
      ; Compress the directories one by one in the zip using the listfile.... Local $iPID = RunWait(@ScriptDir & "\bin\7zG.exe a -mx" & $compressionQuality & " -v" & $compressSplitFileSize & " -wc:\temp " _ & $backupToLocation & "\" & $userDirectory & ".7z @bin\listfile.txt -x@bin\excludefile.txt", "", @SW_SHOWDEFAULT, $STDOUT_CHILD) Ultimately I would love to switch entirely to 7za.exe (standalone) so that I can read the progress percentage, current file being uploaded and any warnings or errors could be processed and output to the AutoIT script's GUI I've created rather than jumping in and out of two applications per se.
       
×