Simulate Key Strokes to a Dos program

How can a simulate key strokes to a Dos Program running under Windows95?

My app need to lunch an app and time a five minutes delay before it ask it to quit, usualy by sending key strokes in series like "alt-x, n" or "F10, Y". My user will tell the corect sequence to send. But I must know how to send them!

ps: I know it can be done, the ScriptTools and ScriptRunner of PcTools 2.0 for Windows 3.1 does it wonderfully under both 3.1 and 95.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Hummm... 16-bits I'm not sure of, 32-bits I might have a solution for. One question, though, do you need to be able to send just *some* keystrokes? I've already written a 32-bit class allowing you to redirect *all* input/output to/from a console/dos app, if you need to control only parts of the input it won't do.


lmarceauAuthor Commented:
Edited text of question
This code should get you started.

Just create a form with a single button and use this code for the OnClick handler. Remember to replace the hardcoded path in CreateProcess with e.g. path to

This code will simply send an ENTER every 2 seconds until the dos app quits.

procedure TForm1.Button1Click(Sender: TObject);
  si      : TStartupInfo;
  pi      : TProcessInformation;
  ir      : ARRAY [0..1] of TInputRecord;
  n       : INTEGER;
  sa      : TSecurityAttributes;
  FillChar(si, SizeOf(si), 0);
  si.cb := SizeOf(si);
  CreateProcess('C:\WINNT\SYSTEM32\CMD.EXE', nil, nil, nil, TRUE, 0, nil, nil, si, pi);
  FillChar(ir, SizeOf(ir), 0);
  ir[0].EventType := KEY_EVENT;
  with ir[0].KeyEvent do begin
    bKeyDown := TRUE;
    wRepeatCount := 1;
    wVirtualKeyCode := VK_RETURN;
    AsciiChar := #13;
  ir[1] := ir[0];
  ir[1].KeyEvent.bKeyDown := FALSE;
    WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ir[0], 2, n);
  until WaitForSingleObject(pi.hProcess, 0) = WAIT_OBJECT_0;

The important parts here are:

AllocConsole - Creates a console owned by your app.

TRUE for bInheritHandles in CreateProcess - The dos app will use the already existing console, still owned by your app.

FreeConsole - Removes the console owned by your app.

The TInputRecord array is necessarry because you normally needs to send both key-down and key-up to the app. Look up WriteConsoleInput in API help, look at the INPUT_RECORD and then KEY_EVENT_RECORD topic. You'll probably need to use the dwControlKeyState flag to simulate ALT and so on. Some error-checking might be an idea too.



Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

lmarceauAuthor Commented:
I've copy/pasted your code in Delphi developper 2.0.
The console boot ok. Prety cool right.
But the key aren't sent. Can you find out why?
Win 95 or NT ?? Version?

Are the path and filename in CreateProcess correct?

What return values do you get from CreateProcess and WriteConsoleInput? What are the values returned if calling  GetLastError after these calls?


lmarceauAuthor Commented:
Escuse me for the delay. I'm back now.

The answers to your questions are:
I'm under Win95, Delphi 2.0

While running your code:
Console created ok
Process created ok in the console ('c:\') CreateProcess returns 1, GetLastError (just after the call to createprocess) returns 6  (what does that means? where can I get a list of error code?)

Key not sent (I've added a feed back on the form, 'Sent' is beaing textout on the form every two second but the keys aren't sent)
WriteConsoleInput returns 1, GetLastError (just after the call to WriteConsoleInput) returns 6 too.

Hope this help, my shipping deadline is now aproaching!
lmarceauAuthor Commented:
Well, my deadline had gone though and I had to ship without the feature/ But a still need a solution.
Please help me. You seem to have a more powerfull solution than anyone else.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.