user2732180
user2732180

Reputation: 175

How to close a child command window when using Start.Process();

I'm looking to trigger the child command window's close event once its command is finished. Keep in mind, it's a background process initiated from a console app so it's never visible. What is visible is the console application.

I tried using the Exited event, but that didn't work. I tried relying on CMD to know when to close it by using /c, /k, and exit. Neither seem to work. I also tried a do while loop checking HasExited, none of these have worked unless I type "exit" within the application console window. It does not close, but somehow triggers the invisible child command windows to close.

Is there another way of closing it once the child command is complete?

String msg = "echo %time%; exit;";  
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = msg;
p.EnableRaisingEvents = true;
p.Exited += p_Exited; 
p.Start();
msg += p.StandardOutput.ReadToEnd();

Thank you very much!!

Upvotes: 0

Views: 502

Answers (1)

GregC
GregC

Reputation: 8007

I modified your program slightly to run a child command processor, capture its output, then write it to console.

        char quote = '"';
        string msg = "/C " + quote + "echo %time%" + quote;
        System.Diagnostics.Process p = new System.Diagnostics.Process();
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.Arguments = msg;
        p.EnableRaisingEvents = true;
        p.Exited += (_, __) => Console.WriteLine("Exited!");
        p.Start();
        string msg1 = p.StandardOutput.ReadToEnd();

        Console.WriteLine(msg1);

Here's a full program, using slightly different syntax, but similar in spirit:

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            char quote = '"';
            var startInfo = new ProcessStartInfo("cmd", "/C " + quote + "echo %time%" + quote)
            { UseShellExecute = false, RedirectStandardOutput = true };

            var process = new Process { EnableRaisingEvents = true };
            process.StartInfo = startInfo;
            process.Exited += (_, __) => Console.WriteLine("Exited!");
            process.Start();
            string msg1 = process.StandardOutput.ReadToEnd();

            Console.WriteLine(msg1);

            Console.ReadLine();
        }
    }
}

Or, as this answer illustrates, maybe just call DateTimeOffset.Now. If you're interested in looking at sub-second info, maybe use Stopwatch class instead.

If you prefer to drive command line with commands from C#, it's also possible. Igor Ostrovsky describes how to convert events to Tasks; then use async/await to create a procedural-looking sequence of commands and responses.

Upvotes: 1

Related Questions