创建一个cmd窗口并从C#应用程序写入它 [英] Create a cmd window and write to it from C# application
问题描述
我正在为Rhino的Grasshopper开发C#组件。当我运行一些非常繁重的迭代分析时,我想将结果连续输出到cmd窗口,只是为了确保分析实际上在运行。
I am developing a C# component for Grasshopper for Rhino. As I am running some pretty heavy iterative analysis I would like to output results continuously to a cmd window just to make sure that the analysis is actually running.
这就是我尝试过的:
using System.Diagnostics;
Result results = new Result();
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
do {
results = RunHeavyOperation(results);
cmd.StandardInput.WriteLine("echo " + results.usefulInfo);
} while (!results.conditionForEnd);
cmd.WaitForExit();
Result RunHeavyOperation(Result previousResults) {
Result res = doHeavyStuff(previousResults);
return res;
}
我意识到我缺少一部分,但这是什么?
I realise that I am missing part, but what is it?
推荐答案
您的方法是错误的:您当前未写入控制台窗口。相反,您通过启动 cmd.exe
创建了一个进程,并写入该进程的标准输入管道。 cmd.exe
不知道。这与通过键盘输入控制台不同,甚至会产生奇怪的效果。
想象一下您输出了一个新的换行符,所以 cmd.exe
可能会尝试执行命令之前输出的内容。
Your approach is wrong: You currently don't write to a console window. Instead you created a process by starting cmd.exe
and write to the standard input pipe of that process. cmd.exe
is not aware of that. It's not the same as typing in a console via your keyboard, and even that can have strange effects.
Imagine you output a new line character, so cmd.exe
might try to "execute" what you output before as a command.
正确的方法是调用 AllocConsole
。通过此调用,您可以为进程创建一个控制台窗口,并只需通过 Console.WriteLine()
即可使用它。
The correct way is to invoke AllocConsole
. With this call you can create a console window for your process and use it simply via Console.WriteLine()
.
完成工作和记录后,最终您将需要通过 FreeConsole
。
When you finished your work and logging, you'll eventually need to close and free this console again via FreeConsole
.
因此导入这两个本机方法:
So import these two native methods:
internal sealed class NativeMethods
{
[DllImport("kernel32.dll")]
public static extern bool AllocConsole();
[DllImport("kernel32.dll")]
public static extern bool FreeConsole();
}
并在您的代码中使用它们:
And use them in your code:
NativeMethods.AllocConsole();
// start work
Console.WriteLine("log messages...");
// finished work
NativeMethods.FreeConsole();
请注意, FreeConsole( )
将关闭控制台窗口,因此所有日志消息都会丢失。而且控制台只有很大的缓冲区,如果离开缓冲区,您将无法滚动回到较旧的消息。
Note that FreeConsole()
will close the console window, so all your log messages get lost. And a console only has a so large buffer and you can't scroll back to older messages if the leave the buffer.
因此,简单地编写可能是一个更好的主意将您的日志消息保存到一个文件中,以便以后进行分析。
So it may be a better idea to simply write your log messages into a file that you can analyze later.
这篇关于创建一个cmd窗口并从C#应用程序写入它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!