创建cmd窗口并从C#应用程序写入
我正在为犀牛的蚱蜢开发一个C#组件。当我运行一些非常繁重的迭代分析时,我希望将结果连续输出到cmd窗口,以确保分析实际正在运行 以下是我尝试过的:创建cmd窗口并从C#应用程序写入,c#,cmd,stdout,stdin,C#,Cmd,Stdout,Stdin,我正在为犀牛的蚱蜢开发一个C#组件。当我运行一些非常繁重的迭代分析时,我希望将结果连续输出到cmd窗口,以确保分析实际正在运行 以下是我尝试过的: using System.Diagnostics; Result results = new Result(); Process cmd = new Process(); cmd.StartInfo.FileName = "cmd.exe"; cmd.StartInfo.RedirectStandardInput = true; cmd.Star
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;
}
我意识到我缺少了这个部分,但它是什么呢?在Visual Studio中创建一个控制台应用程序。在VS 2017中,情况如下(在起始页): 控制台应用程序自动打开命令控制台。然后你就可以用它来写了
Console.WriteLine("hello");
当程序终止时,控制台自动关闭。所以一定要调用
Console.ReadKey()如果您想让它保持打开状态,请在结尾处使用code>。您的方法是错误的:您当前没有写入控制台窗口。而是通过启动cmd.exe
并写入该进程的标准输入管道来创建一个进程cmd.exe
不知道这一点。这与通过键盘在控制台中输入不同,甚至可能产生奇怪的效果。
假设您输出了一个新行字符,cmd.exe
可能会尝试“执行”以前作为命令输出的内容
正确的方法是调用。通过此调用,您可以为流程创建一个控制台窗口,并通过console.WriteLine()
简单地使用它
当您完成工作和日志记录后,最终需要通过关闭并释放此控制台
因此,请导入这两种本机方法:
internal sealed class NativeMethods
{
[DllImport("kernel32.dll")]
public static extern bool AllocConsole();
[DllImport("kernel32.dll")]
public static extern bool FreeConsole();
}
并在代码中使用它们:
NativeMethods.AllocConsole();
// start work
Console.WriteLine("log messages...");
// finished work
NativeMethods.FreeConsole();
请注意,FreeConsole()
将关闭控制台窗口,因此所有日志消息都将丢失。控制台只有这么大的缓冲区,如果用户离开缓冲区,您就无法滚动回旧消息
因此,最好将日志消息写入一个文件中,以便以后分析 作为记录,我使用System.Diagnostics.Debug.Write(results.usefulInformation)临时解决了这个问题代码>,但如果应用程序进入生产环境,这将不起作用。这一切都很好,但应用程序已经在深入开发-将现有应用程序迁移到控制台应用程序是否容易?这取决于您是否已经制作了WinForms或WPF应用程序并创建了UI,或者您是否只编写了业务逻辑。在后一种情况下,您将不需要进行任何转换。当然,应用程序不能同时是控制台和WinForms或WPF应用程序。是的,这就是我要找的。谢谢我可以在winforms应用程序中执行此操作吗?我可以打开控制台,但没有写入任何内容@OlivierJacot Descombes是的,你可以,我刚刚再次测试了它,它对我有效。我必须使用来自answer的代码使它工作。但当从VS2017内启动应用程序时,输出仍然重定向到调试输出窗口。它只在从外部启动应用程序时有效,而@OlivierJacot Descombes它在VS2017内部对我有效。你是从附加的调试器开始的吗?那当然不行了,因为已经有了一种控制台(调试器)。因为OP希望它在生产环境中工作,所以我认为我的代码还可以。如果启动时不进行调试,它会工作。