繁体   English   中英

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

[英]Create a cmd window and write to it from C# application

我正在为Rhino的Grasshopper开发一个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;
}

我意识到我错过了一部分,但它是什么?

您的方法是错误的:您当前没有写入控制台窗口。 相反,您通过启动cmd.exe并写入该进程标准输入管道来创建进程 cmd.exe不知道这一点。 这与通过键盘输入控制台不同,甚至可能产生奇怪的效果。
想象一下,您输出一个新的行字符,因此cmd.exe可能会尝试“执行”您之前输出的内容作为命令。

正确的方法是调用AllocConsole 通过此调用,您可以为流程创建一个控制台窗口,并通过Console.WriteLine()简单地使用它。

完成工作和日志记录后,最终需要通过FreeConsole关闭并再次释放此控制台。

所以导入这两个本机方法:

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()关闭控制台窗口,因此所有日志消息都会丢失。 并且控制台只有一个如此大的缓冲区,如果离开缓冲区,则无法滚动回较旧的消息。

因此,将日志消息简单地写入您可以在以后分析的文件中可能是一个更好的主意。

在Visual Studio中创建控制台应用程序。 在VS 2017中它看起来像这样(在开始页面上):

在此输入图像描述

控制台应用程序自动打开命令控制台 然后你可以写信给它

Console.WriteLine("hello");

程序终止时控制台自动关闭。 所以一定要调用Console.ReadKey(); 最后,如果你想保持开放。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM