|
-
Feb 6th, 2009, 05:19 AM
#1
Thread Starter
Junior Member
Sending Keys to a Process??
Hi,
I have an external exe file that runs like a console aplication (CLI). It is started as a process and is embedded in a Panel on a form.
I can type commands directly at its prompt, but I would also like to send it keystrokes from a button.
Here is the code that starts it, embeds it into a Panel, removes its TitleBar, and positions and sizes it to the size of the Panel.
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim p As New System.Diagnostics.ProcessStartInfo
p.FileName = "C:\Program Files\Console2\Console.exe"
proc.StartInfo = p
proc.Start()
proc.WaitForInputIdle()
SetParent(proc.MainWindowHandle, Panel1.Handle)
SendMessage(proc.MainWindowHandle, WM_SYSCOMMAND, SC_RESTORE, 0)
InitialStyle = GetWindowLong(proc.MainWindowHandle, GWL_STYLE)
SetWindowLong(proc.MainWindowHandle, -16, InitialStyle And Not WS_DLGFRAME)
MoveWindow(proc.MainWindowHandle, Panel1.Left, Panel1.Top, Panel1.Width, Panel1.Height, True)
End Sub
I wondered if SendKeys would work, but the documentation says it should be sent to the 'active window', but there I get confused, as my exe is a process, and I do not know if the Panel it is embedded into is the 'window' referred to, or the proc.MainWindowHandle, and I do not know whether it is active or not.
How should I go about this?
Edit: Just tried this, but I get an error at the AppActivate line: Process '{0}' was not found, even though the MessageBox correctly reports that the Window Title of the process is "Console".
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim p As New System.Diagnostics.ProcessStartInfo
p.FileName = "C:\Program Files\Console2\Console.exe"
pproc.StartInfo = p
proc.Start()
proc.WaitForInputIdle()
SetParent(proc.MainWindowHandle, Panel1.Handle)
SendMessage(proc.MainWindowHandle, WM_SYSCOMMAND, SC_RESTORE, 0)
InitialStyle = GetWindowLong(proc.MainWindowHandle, GWL_STYLE)
SetWindowLong(proc.MainWindowHandle, -16, InitialStyle And Not WS_DLGFRAME)
MoveWindow(proc.MainWindowHandle, Panel1.Left, Panel1.Top, Panel1.Width, Panel1.Height, True)
MsgBox(proc.MainWindowTitle)
AppActivate(proc.MainWindowTitle)
SendKeys.SendWait("dir" & "{Enter}")
End Sub
Any ideas?
TIA
Rock
-
Feb 6th, 2009, 06:31 AM
#2
Hyperactive Member
Re: Sending Keys to a Process??
I found the following remark in the Visual Studio help for AppActivate:
"You can use AppActivate only with processes that own windows. Most console applications do not own windows, which means that they do not appear in the list of processes that AppActivate searches. When running from a console application, the system creates a separate process to run the application and returns the output to the console process. Consequently, when you request the current process ID, you get the process ID of this separate process, rather than the console application's process ID."
Runesmith
The key to getting the right answer is asking the right question
I just realized: good health is merely the slowest possible rate at which one can die
-
Feb 6th, 2009, 08:34 AM
#3
Thread Starter
Junior Member
Re: Sending Keys to a Process??
 Originally Posted by Runesmith
I found the following remark in the Visual Studio help for AppActivate:
"You can use AppActivate only with processes that own windows. Most console applications do not own windows, which means that they do not appear in the list of processes that AppActivate searches. When running from a console application, the system creates a separate process to run the application and returns the output to the console process. Consequently, when you request the current process ID, you get the process ID of this separate process, rather than the console application's process ID."
Thank you so much for that Runesmith. That explains a lot. I found lots of similar posts about AppActivate errors in other forums, and no answer to any of them. Well done. This will save me heading down the wrong path.
I may abandon SendKeys then (as I cant think how I can overcome the 'active window' problem), and look at the SendMessage or StreamWriter alternatives instead.
SendMessage also seems to have issues, accroding to several posts I have seen in other forums, so I will look first at StreamWriter (temporarily redirecting input, sending a message via StreamWriter, then restoring normal input).
Anyone got any experience of successfully sending a command, such as dir<Enter> to a cmd console, using either the SendMessage API, or by redirection and using StreamWriter?
Rock
-
Feb 6th, 2009, 04:36 PM
#4
Re: Sending Keys to a Process??
Could you use the SetForegroundWindow API with the MainWindowHandle of the process? Then I think SendKeys would work.
-
Feb 6th, 2009, 05:16 PM
#5
Thread Starter
Junior Member
Re: Sending Keys to a Process??
 Originally Posted by Negative0
Could you use the SetForegroundWindow API with the MainWindowHandle of the process? Then I think SendKeys would work.
Many thanks Negative0, SetForegroundWindow did enable SendKeys to work. However, it did develop a bad case of the stutter, even with a couple of pauses thrown in, as this screenshot shows.
Any idea why the stuttering occurs?
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim p As New System.Diagnostics.ProcessStartInfo
p.FileName = "C:\Program Files\Console2\Console.exe"
proc.StartInfo = p
proc.Start()
proc.WaitForInputIdle()
SetParent(proc.MainWindowHandle, Panel1.Handle)
SendMessage(proc.MainWindowHandle, WM_SYSCOMMAND, SC_RESTORE, 0)
InitialStyle = GetWindowLong(proc.MainWindowHandle, GWL_STYLE)
SetWindowLong(proc.MainWindowHandle, -16, InitialStyle And Not WS_DLGFRAME)
MoveWindow(proc.MainWindowHandle, Panel1.Left, Panel1.Top, Panel1.Width, Panel1.Height, True)
SetForegroundWindow(proc.MainWindowHandle)
System.Threading.Thread.Sleep(1000)
SendKeys.Send("dir")
System.Threading.Thread.Sleep(1000)
SendKeys.Send("{Enter}")
End Sub
Thanks again,
Rock
-
Feb 6th, 2009, 05:29 PM
#6
Re: Sending Keys to a Process??
Try using SendWait instead to see if that helps.
-
Feb 6th, 2009, 05:31 PM
#7
Thread Starter
Junior Member
Re: Sending Keys to a Process??
 Originally Posted by Negative0
Try using SendWait instead to see if that helps.
I was just about to Edit my post to say that I had also tried SendWait with no change, but you got there ahead of me!
Rock
-
Feb 6th, 2009, 05:38 PM
#8
Re: Sending Keys to a Process??
What about sending 1 character at a time?
-
Feb 6th, 2009, 05:44 PM
#9
Thread Starter
Junior Member
Re: Sending Keys to a Process??
 Originally Posted by Negative0
What about sending 1 character at a time?
One character also repeats. I started playing with different sleep values, when I finally got up to 9 seconds (!!!) it behaved and the dir command executed.
Code:
SetForegroundWindow(proc.MainWindowHandle)
System.Threading.Thread.Sleep(9000)
SendKeys.SendWait("dir")
SendKeys.SendWait("{Enter}")
A Google for 'SendKeys' and 'Repeated' brought up posts on other forums from as far back as 2005 showing the same repetition as in my screenshot, and none had an answer 
Rock
-
Feb 9th, 2009, 11:22 AM
#10
Thread Starter
Junior Member
Re: Sending Keys to a Process??
Having learnt a lot now about the vagaries of SendKeys, its unreliability, its lack of cohesion across platforms, and its dangers, I have decided to abandon this approach.
However, with what should I replace it?
Just to recap, I am embedding a cmd console window inside a panel, positioning and resizing it to the dimensions of the Panel, and I want to be able to both type commands at the prompt AND be able to click buttons on my form that will send it various commands.
So, if SendKeys is not the answer, how about:
a) SendInput
b) StreamWriter
c) SendMessage
d) None of the above
I would welcome suggestions/advice on which is the best method to send text commands to a cmd window.
TIA
Rock
-
Feb 9th, 2009, 01:12 PM
#11
Re: Sending Keys to a Process??
If you are trying to use the command line, then I would start with RedirectStandardInput/Output.
It looks like you have replied on this thread, but it is a good starting point:
http://www.vbforums.com/showthread.p...hlight=Console
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|