在Windows窗体中嵌入DOS控制台

时间:2022-09-19 15:52:34

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

是否可以在Windows窗体或C#2.0中的用户控件中嵌入DOS控制台?

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.

我们有一个我的Windows应用程序必须与之交互的遗留DOS产品,并且已经要求遗留产品的实例应该在Windows应用程序中运行。

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.

目前,我正在使用user32.dll找到运行DOS产品的窗口,最小化然后最大化窗口,并在窗口中键入字符。这不是解决问题的非常好的解决方案,因为这意味着我的应用程序必须将窗口名称存储在应用程序设置中,并要求用户在使用交互功能之前返回到DOS应用程序的正确页面。

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.

我已经尝试了TimothyP的答案并且它运行得很好,但它是否可以实现相同的功能,但DOS窗口可视化地嵌入在窗体或用户控件中而不是弹出它自己的窗口?优选地,以ShowDialog()方式使得用户不能与应用程序交互,他们处于“传统模式”,可以这么说。

3 个解决方案

#1


22  

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

可以使用Process类重定向控制台/ dos应用程序的标准输入/输出。它可能看起来像这样:

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.

您现在可以使用流与应用程序进行交互。通过将processStartInfo.CreateNoWindow设置为true,将隐藏原始应用程序。

I hope this helps.

我希望这有帮助。

#2


4  

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

关于如何在Windows应用程序中显示DOS应用程序的问题。

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.

    第一个是简单地不显示DOS应用程序(使用CreateNoWindow)并通过读取和写入流来“模拟”Windows应用程序中DOS应用程序的UI。

  • 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:

    另一种解决方案是使用Win32API,获取Console / DOS应用程序窗口的Windows句柄(Whnd)并将其父级设置为您的表单。我现在不在家,因为自从我这么做以来已经很久了,我不记得它是如何完成的。如果我没弄错,你需要使用以下Win32 API调用:

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

如果我今天晚些时候还有一些时间,我会看看能不能找到更好的样品。

#3


1  

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.

您可以使用CreateProcess函数以及STARTUPINFO参数的hStdInput,Output和Error成员,这将允许您拦截应用程序的标准输入和输出。

#1


22  

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

可以使用Process类重定向控制台/ dos应用程序的标准输入/输出。它可能看起来像这样:

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.

您现在可以使用流与应用程序进行交互。通过将processStartInfo.CreateNoWindow设置为true,将隐藏原始应用程序。

I hope this helps.

我希望这有帮助。

#2


4  

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

关于如何在Windows应用程序中显示DOS应用程序的问题。

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.

    第一个是简单地不显示DOS应用程序(使用CreateNoWindow)并通过读取和写入流来“模拟”Windows应用程序中DOS应用程序的UI。

  • 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:

    另一种解决方案是使用Win32API,获取Console / DOS应用程序窗口的Windows句柄(Whnd)并将其父级设置为您的表单。我现在不在家,因为自从我这么做以来已经很久了,我不记得它是如何完成的。如果我没弄错,你需要使用以下Win32 API调用:

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

如果我今天晚些时候还有一些时间,我会看看能不能找到更好的样品。

#3


1  

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.

您可以使用CreateProcess函数以及STARTUPINFO参数的hStdInput,Output和Error成员,这将允许您拦截应用程序的标准输入和输出。