C# 在 Windows 窗体中嵌入 DOS 控制台

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/355724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:18:44  来源:igfitidea点击:

Embedding a DOS console in a windows form

c#winformsc#-2.0dos

提问by Mark Withers

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

是否可以在 C# 2.0 中的 Windows 窗体或用户控件中嵌入 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.

我们有一个旧版 DOS 产品,我的 Windows 应用程序必须与之交互,并且要求旧版产品的实例应在 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 窗口可视化地嵌入到 Windows 窗体或用户控件中,而不是在它自己的窗口中弹出?最好采用 ShowDialog() 方式,这样用户就无法在“传统模式”下与应用程序交互,可以这么说。

采纳答案by TimothyP

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.

我希望这有帮助。

回答by Frans-Willem

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 成员,这将允许您拦截应用程序的标准输入和输出。

回答by TimothyP

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.

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

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

  • 另一种解决方案是使用 Win32API,获取控制台/DOS 应用程序窗口的 Windows 句柄 (Whnd) 并将其父级设置为您的窗体。我现在不在家,自从我这样做已经有很长时间了,我记不清是怎么做的了。如果我没记错的话,您将需要使用以下 Win32 API 调用:

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

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