Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建cmd窗口并从C#应用程序写入_C#_Cmd_Stdout_Stdin - Fatal编程技术网

创建cmd窗口并从C#应用程序写入

创建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

我正在为犀牛的蚱蜢开发一个C#组件。当我运行一些非常繁重的迭代分析时,我希望将结果连续输出到cmd窗口,以确保分析实际正在运行

以下是我尝试过的:

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()

您的方法是错误的:您当前没有写入控制台窗口。而是通过启动
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希望它在生产环境中工作,所以我认为我的代码还可以。如果启动时不进行调试,它会工作。