Solved

interacting with a process

Posted on 2010-09-06
15
1,114 Views
Last Modified: 2012-05-10
Hello, I am attempting to interact with a process that I launch. I need to monitor its output and enter key strokes in response to the output from the process. I cannot wait for the process to exit before seeing and responding to its output. Here is a simple example of what I am talking about as what you would see if using a cmd window:

C:\STMFlashLoader.exe -c --pn 17 --br 115200
Opening Port              [OK]
 Press any key to continue...

I have code working that allows me to monitor the output, but am unable to "send keys" with stream or sendkeys. I would like a structure such that I can monitor the output and when I see certain strings, respond by sending an appropriate string back to the process, and continue to monitor and again, send an appropriate string until the process exits or I terminate the process.

Here is the code I have working at this point


Dim start_info As New ProcessStartInfo("C:\Program Files\STMicroelectronics\Software\Flash Loader Demonstrator\STMFlashLoader.exe")
start_info.Arguments = "-c --pn 17 --br 115200"
start_info.UseShellExecute = False
start_info.CreateNoWindow = True
start_info.RedirectStandardOutput = True
start_info.RedirectStandardError = True

 ' Make the process and set its start information.
  Dim proc As New Process()
  proc.StartInfo = start_info

    ' Start the process.
     proc.Start()


  ' Attach to stdout and stderr.
  Dim std_out As StreamReader = proc.StandardOutput()
   Dim std_err As StreamReader = proc.StandardError()

       
        ' Display the results.
  txtStdout.Text = std_out.ReadToEnd()
   txtStderr.Text = std_err.ReadToEnd()

    ' Clean up.
  std_out.Close()
  std_err.Close()
   proc.Close()

Much thanks,
bartj












0
Comment
Question by:bartdsp
  • 6
  • 4
  • 3
  • +2
15 Comments
 
LVL 12

Expert Comment

by:Mohamed Abowarda
ID: 33614371
To get the keystrokes, get the window handle and whenever the window is active use GetAsyncKeyState API:

http://msdn.microsoft.com/en-us/library/ms646293(v=VS.85).aspx
0
 
LVL 7

Expert Comment

by:Inteqam
ID: 33614906
i think this depends on the application, what if the process is windowless?!
0
 

Author Comment

by:bartdsp
ID: 33614997
Inteqam,

Note sure I understand your question. The exe(STMFlashLoader.exe) that I "call", does have a window(DOS) when called from the command line, but if you are asking  if it needs to be visible, the answer is no. Let me know if that answers your question.

Thanks,
Bart




0
 
LVL 7

Expert Comment

by:Inteqam
ID: 33615516
yes,
so, how are you to record actions on it if it is not visible?
0
 

Author Comment

by:bartdsp
ID: 33618376
As you can see from my code example I I can monitor the output via re-directed stdout. In this case I have it sent to a text box. This could just as easily be directed to string (buffer) where I could monitor the output instead of a textbox.

Make sense?
0
 
LVL 21

Expert Comment

by:mastoo
ID: 33618897
I think we're saying it is a console application so windows messaging doesn't help.  Interprocess Communication can range from writing to a file (and the other app polls the file), to sockets or named pipes, or you could make a remoting server component.  I'd be inclined to just poll a file unless you need a better response, then named pipes are old fasioned but easy to do.  You can easily use a named mutex with a file to avoid the two programs running into each other on file access.
0
 

Author Comment

by:bartdsp
ID: 33619050
Besides needing to grab the data (file, pipes, sockets, etc) there is the need to send  characters to the console application.
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 21

Expert Comment

by:mastoo
ID: 33619188
Can't say I'm an expert in this area but I think the only way to do that is your app needs to redirect stdin also.  Your app can then feed characters to stdin of the console app.  So now the question becomes, how does your app know what to feed it?  It either gets this from elsewhere (a file, pipes, sockets, etc.) or it could easily be a gui that is displaying stdout results and accepting or deciding on things to send to stdin.
0
 

Author Comment

by:bartdsp
ID: 33619313
I was attempting to re-direct stdin but was having problems with implementation. I would imagine the code would spin in a loop while the app is still responding, looking for (for example): "press any key to continue" If that string is found, the app would send a space key, then continue to look for similar messages.

The 2 basic criteria: Receive data while the console app is running(not after it has terminated) and be able to send characters to the console app.

0
 
LVL 21

Accepted Solution

by:
mastoo earned 500 total points
ID: 33619943
You'll need asynchronous redirection.  If you look at your VS help, Process.BeginOutputReadLine has an example.  It is complicated, but I think it is the only way to do what you describe.  I'm assuming here that you don't have the option of modifying the console app that you are invoking.
0
 
LVL 7

Expert Comment

by:Inteqam
ID: 33622738
I apologise, my comment was for Medo3337.

0
 
LVL 29

Expert Comment

by:matrixnz
ID: 33626203
Here is how I'd do it in AutoIT which is based on the same principal, basically capture the output in a loop and as you suggested send keys then wipe the output so that it doesn't continue to hit the send key.

For more instructions just use elseif StringInStr($CHK_FLASHLOADER, .... etc.. and add other send keys.

Hope that made sense.

Cheers
#NoTrayIcon

#include <Constants.au3>



$RUN_FLASHLOADER = Run('"' & @ProgramFilesDir & '\STMicroelectronics\Software\Flash Loader Demonstrator\STMFlashLoader.exe" -c --pn 17 --br 115200', '', @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

$CHK_FLASHLOADER = ''

$ERR_FLASHLOADER = ''



	While 1

		$CHK_FLASHLOADER &= StdoutRead($RUN_FLASHLOADER)

		If @error Then ExitLoop

		If StringInStr($CHK_FLASHLOADER, 'Press any key to continue...') Then

			Send('{Space}')

			$CHK_FLASHLOADER = ''

		EndIf

	WEnd



	While 1

		$ERR_FLASHLOADER &= StderrRead($RUN_FLASHLOADER)

		If @error Then ExitLoop

	WEnd

Open in new window

0
 

Author Comment

by:bartdsp
ID: 33663825
All,

I tried the following and am still unable to monitor the process until after the exe that I am calling has exited. Note that I have a timer firing every 200 ms in an attempt to gather the data and display. I am not yet attempting to send keys. If I send the exe name and parameters in a dos window I get streaming data in a dos window for 20 seconds telling me about the process. If sending via my code I get the data only after 20 seconds has elapsed.

Comments?....

Sub ProcessTest()


        Try
            ' Initialize the process and its StartInfo properties.
            Dim myProcess As New Process()
            Dim numInputLines As Integer = 0

            Bigmessage = ""


            myProcess.StartInfo.FileName = "C:\Program Files\STMicroelectronics\Software\Flash Loader Demonstrator\STMFlashLoader.exe"
            myProcess.StartInfo.Arguments = "-c --pn 17 --br 115200 -i STM32_Med-density_128K -u --fn c:\qaz.hex"

            ' Set UseShellExecute to false for redirection.
            myProcess.StartInfo.UseShellExecute = False

            ' Redirect the standard output of the sort command.  
            ' Read the stream asynchronously using an event handler.
            myProcess.StartInfo.RedirectStandardOutput = True
            sortOutput = New StringBuilder()

            ' Set our event handler to asynchronously read the sort output.
            AddHandler myProcess.OutputDataReceived, AddressOf MyOutputHandler

            ' Redirect standard input as well.  This stream is used synchronously.
            myProcess.StartInfo.RedirectStandardInput = True

            ' Start the process.
            myProcess.Start()

            ' Use a stream writer to synchronously write .
            Dim myStreamWriter As StreamWriter = myProcess.StandardInput

            ' Start the asynchronous read of the sort output stream.
            myProcess.BeginOutputReadLine()

            ' End the input stream to the sort command.
            myStreamWriter.Close()

            ' Wait
            myProcess.WaitForExit()


            myProcess.Close()


        Catch

            MsgBox("Process test: " & Err.Description)
        End Try

    End Sub

    Sub MyOutputHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs)


        Try
            Dim msg As String

            Application.DoEvents()

            If outLine.Data.ToString = Nothing Then Exit Sub
           
            msg = outLine.Data.ToString

            If Not msg = "" Then

                Bigmessage = Bigmessage & msg
                numOutputLines = numOutputLines + 1

            End If

        Catch

            MsgBox("Handler: " & Err.Description)

        End Try

    End Sub
0
 
LVL 21

Assisted Solution

by:mastoo
mastoo earned 500 total points
ID: 33664610
This runs from a gui with a timer that is checking Bigmessage?

Two things I note: I assume MyOutputHandler gets its callback from a background thread, so DoEvents and MsgBox shouldn't be used there.  And is the other app looking for input on stdin?  I'm not sure how it will react but you close the redirected input stream immediately.  This is why I said it would be complicated.  I'm thinking you need to keep the input stream open while watching the output from stdout, and respond on stdin based on what stdout does.
0
 

Author Closing Comment

by:bartdsp
ID: 33756388
All, I ended up getting my hands on the source for the console app and modified so that I did not need to send it any key info. Then I used a process and a handler:

            ' define a process
            Dim p As New Process

            p.StartInfo.FileName = filename
            p.StartInfo.Arguments = parametrers

            ' setup
            p.StartInfo.UseShellExecute = False
            p.StartInfo.RedirectStandardOutput = True
            p.StartInfo.CreateNoWindow = True

            ' add a handler so we can easily display the data
            AddHandler p.OutputDataReceived, AddressOf Showme
           
            p.Start()
            p.BeginOutputReadLine()

            Application.DoEvents()

            ' spin here till done or cancel
            Do While (p.HasExited = False) And (CANCEL = False)
                ' monitor progress
                Application.DoEvents()
            Loop

            If CANCEL = True Then
                p.Kill()
                p.Dispose()
                Return False
            End If

            p.Dispose()
            Return true

   
    End Function
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now