views:

2230

answers:

3

Is it possible to embed a DOS console in a Windows Form or User Control in C# 2.0?

We have a legacy DOS product that my Windows app has to interact with, and it's been requested that an instance of the legacy product should run within the Windows application.

At the moment, I'm using the user32.dll to locate the window that the DOS product is running in, minimising then maximising the window, and typing characters into the window. This isn't a very good solution to the problem, as it means my application has to store the window name in application settings, and requires that the user returns to the correct page of the DOS app before using the interaction function.

EDIT: Some more information

The legacy app needs to be visible to the user, but not in a separate window.

I've tried TimothyP's answer and it works very well, but is it possible to achieve the same functionality, but with the DOS window visually embedded in a windows form or user control instead of popping up in it's own window? Preferably in a ShowDialog() way so that the user cannot interact with the app wile they are in 'Legacy Mode', so to speak.

+1  A: 

You can use the CreateProcess function and the hStdInput, Output, and Error members of the STARTUPINFO argument, this will allow you to intercept standard input and output of the application.

Frans-Willem
+4  A: 

It's possible to redirect the standard input/output of console/dos applications using the Process class. It might look something like this:

var processStartInfo = new ProcessStartInfo("someoldapp.exe", "-p someparameters");

processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;

processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.CreateNoWindow = true;

Process process = new Process();
process.StartInfo = processStartInfo;
bool processStarted = process.Start();

StreamWriter inputWriter = process.StandardInput;
StreamReader outputReader = process.StandardOutput;
StreamReader errorReader = process.StandardError;
process.WaitForExit();

You can now use the streams to interact with the application. By setting processStartInfo.CreateNoWindow to true the original application will be hidden.

I hope this helps.

TimothyP
+2  A: 

Concerning your question on how to display the DOS app inside the Windows app.

There are a few solutions.

  • The first one is to simply not display the DOS app (with CreateNoWindow) and "simulate" the UI of the DOS app in your Windows application by reading and writing to the streams.

  • The other solution would be to use the Win32API, get the Windows Handle (Whnd) of the Console/DOS application window and set its parent to your form. I'm currently not at home and since it has been ages since I've done this, I can't remember by heart how it is done. If I'm not mistaken you'll need to use the following Win32 API calls:

If I have some time left later today, I'll see if I can find better samples.

TimothyP
Thanks Timothy, I've already used the FindWindow and GetWindow API calls, I'll look into SetParent today.Thanks again for your help! Hopefully I'll be able to return the favour one day.
Mark Withers