Programmers: how to make a program "type" into another

At work, we have an old mini-frame application that uses terminals and terminal emulation for its interface (both via serial communication). There is useful data that is readily available through terminals and the system’s printer. It would be quite helpful to pull that data into a modern database.

Because the reports that gather the data are already exising in the system, my idea was to write a PC program that would communicate with the miniframe through the COM port. It would just act like a user on a terminal, hitting the right menu choices, then parsing and interpreting the data that comes out.

As a shortcut to writing a terminal emulator, I thought we could just use the terminal emulator we already have running on PCs. The emulator software already can write out files of each of the screens it gets.

The question is how my little application can reach over and “type” into it as if someone were typing from the keyboard. I remember from the DOS days that you could run an application with a series of prewritten keystrokes. This won’t work for my application because 1) keystrokes before a screen refresh are ignored, and 2) the keystrokes won’t always be the same (it will depend on what is written out).

Some last details: though we run Win2000 machines, the emulator is an old DOS application. We’ve tried almost every windows-based emulator, but none seem to get the right keys working. The company that made this software is apparently out of business, so we can’t get an updated version. So we’re stuck with this one. When it runs in Win2000, in Task Manager it shows under the application name, and under processes, it appears as NTVDM.exe (NT virtual dos machine, IIRC).

I’ve attempted internet searches for a solution (almost any programming problem seems to have been asked and answered on the 'net), but can’t find the right combination of words to search under.

Since this will be a small program, if there is a solution that is available within a certain programming language, we can pick it up for this.

You can fool Windows into thinking that keys are being pressed. If you know the exact series of keystrokes that you would need to do the task, then you can just automate the process in the program.

Here’s relevant Windows API calls:

Sounds like a job for expect. I’m pretty sure there are versions available for Windows or DOS. If not, you can stick a linux box on that COM port.

I’m not entirly sure I understand the problem.

But, Have you looked at expect scripts? They basically expect a prompt, the repeat what they are told to.

http://expect.nist.gov/

Take a look at AutoIt. AutoIt will let you wait for certain windows to appear and send keystrokes or mouse clicks to the window. It’s a handy little scripting tool that I use frequently when I need to automate tasks.
And, it’s free.

If you’re sure there’s no better way, I third expect. It was tailor-made for just this kind of application.

(In this case a better way would be to find an API or some other hook into the software designed for other programs to access. But if the software writers didn’t design any other interface and it’s closed-source, expect is the best way to go.)

(BTW, what’s a miniframe? I’ve heard of minicomputers like the VAX and the PDP-11 and the System/360 and things like those, and mainframes like the CDC 6600 and the various Cray machines, but I’ve never heard of a miniframe.)

If you have unrestricted access to the “miniframe” then why not just send the data file(s) across the COM port into your PC? Assuming the original application doesn’t have the data encrypted, and you have a pretty good idea of what sort of data you’re looking for, you should be able to figure out the database structure with just a little trolling about with a hex or record editor. Then just write a little program to convert the data to whatever format you want. I have to do this sort of thing frequently and it’s usually a snap.

Best 'o Luck!

This looks like it’s on the right track. However, the documentation seems to be written with the assumption of some previous knowledge of these API calls. What I can’t figure out from the links specified is: can I consistently choose the emulator program that is running and type the characters in it (instead of another window).

Interesting. I’ll have to look deeper into it. So far, it looks like a scripting language. I don’t know if it can be interactive enough for our use. When we enter a command, we could end up with one of several results. Different results will result in different menu choices. I suppose it’s possible to write very short scripts. Also, expect seems to be primarily written around telnet, ftp, etc. If it requires a specific emulator, we’re screwed. We need an IBM 3101 emulator with block mode in which the “SEND” key works.

Writing a program that takes over all COM communication is probably the more stable long-term solution, but it will be nice to use the emulator to get this going quickly, then once the concept has been proved, get the cash money to do the more extensive programming of taking over the COM.

Ooo! Ooo! Ooo! Another contender. I don’t think it will have the ability to interpret the results of the screen outputs, so it will be a question of how well we could get an interpretation program to launch the scripts in AutoIt.

In other words, would AutoIt be interested in a little computing ménage à trois?

I doubt there are any hooks. This is an old emulator (we can’t find a modern one that works). I’ll have to give this Expect a thourough look-at.

Miniframe…that’s what IBM called their Series/1 computer in some of their documentation. They probably thought it sounded snazzier than “minicomputer”.

We do data transfer across the COM port for some data, but holy crap is there some code behind that. If I can just find a way to automate a few keystrokes into my little PCX3101, the pre-written reports run and give relevant data.

Thanks for the luck and thanks for all the replies so far.

Well, I’ve looked at the MSDN documentation, and I believe that this is the procedure you follow:

Create an EVENTMSG structure, E;
E.message = WM_KEYDOWN (it may be KEYPRESSED, not sure).
E.paramL = Virtual key code.
E.paramR = MapVirtualKey(Virtual Key Code, 0)
E.time = GetTickCount
E.hwnd = 0

Create a hook function:

long play(int, LPARAM, RPARAM)

This function returns 0 if the first parameter is HC_GETNEXT. Return the amount of time in ticks to delay if the parameter is HC_SKIP otherwise return CallNextHookEx.

Next, call SetWindowsHookEx(WH_JOURNALPLAYBACK, The above hook function, Program Instance, 0)

That should do it, I think.

Yes, you need to enumerate the window handles and set the window as the active window.

Sorry if it isn;t easy to follow, just ask if you need any help.