简体   繁体   中英

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

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.

Here's what I tried:

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?

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.

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

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

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.

Create a Console App in Visual Studio. In VS 2017 it looks like this (on the start page):

在此输入图像描述

Console apps open a command console automatically. Then you can write to it with

Console.WriteLine("hello");

The console closes automatically when the program terminates. So make sure to call Console.ReadKey(); at the end, if you want to keep it open.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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