1

When you search for a way of executing a command-line-tool or the command-prompt, you find too many results like this question, this question or this article. They all contain solutions to the exact same issue. However, the program I'm currently working on has to execute a command-line-tool almost 500 times. When I do the following:

for (int i = 0; i < 500; i++)
{
    Process.Start("cmd","My Input: " + i);
}

The computer stops responding for a while because too many programs got opened at the same time.

When I do the following:

for (int i = 0; i < 500; i++)
{
    Process.Start("cmd","My Input: " + i);
    System.Threading.Thread.Sleep(myInterval);
}

The program takes too much time to get the job done(I got no problem if my program hangs while executing those commands).

From my point of view, the main reason all this happens is that I keep opening another cmd window each time I run a tool. Could I keep a single cmd window open and keep feeding it commands till I am done? Is there a more efficient way of doing that?

Community
  • 1
  • 1
None
  • 609
  • 7
  • 22
  • If you can you share the name of the tool, maybe someone could suggest a better way or maybe the tool has option to handle multiple inputs. You can execute multiple commands with `&` http://stackoverflow.com/questions/13719174/how-to-execute-multiple-commands-in-a-single-line or http://stackoverflow.com/questions/11010834/how-to-run-multiple-dos-commands-in-parallel – Slai Jan 29 '17 at 18:04

3 Answers3

5

If you can run your commands in parallel, I'd do it as least like this:

Parallel.For(0, 500, new ParallelOptions() {MaxDegreeOfParallelism = 8}, i => {
    var process = Process.Start("cmd", "My Input: " + i);
    process.WaitForExit();
});

So you run commands in parallel, but no more than 8 at the same time, and you wait for command process to exit until starting new one.

What also might help with perfomance is using UseShellExecute and CreateNoWindow flags, like this:

Parallel.For(0, 500, new ParallelOptions() {MaxDegreeOfParallelism = 8}, i => {
    var process = Process.Start(new ProcessStartInfo("cmd", "My Input: " + i) {
        CreateNoWindow = true,
        UseShellExecute = false 
    });
    process.WaitForExit();
});

This might or might not work as expected depending on what kind of process you are execuing. If you just execute some .exe application, this should work just fine and create no windows.

I supposed your "cmd" is just the name of application you want to execute. However, as stated in comments, if you mean cmd.exe application by that - most likely you won't need to execute it. Instead, just execute your application itself, without cmd.exe.

Evk
  • 98,527
  • 8
  • 141
  • 191
2

You don’t need cmd.exe to execute a command-line program. This startup procedure might be faster:

var process = Process.Start(
    new ProcessStartInfo(@"path\to\your\command.exe", "My Input: " + i) {
        /* more options if you like */
        RedirectStandardOutput = true,
        WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
        CreateNoWindow = true
    }
);

process.WaitForExit();
string output = process.StandardOutput.ReadToEnd();

See the documentation for ProcessStartInfo for more available options.

Lumen
  • 3,554
  • 2
  • 20
  • 33
0

Have you tried multithreading the whole thing?

for (int i = 0; i < 500; i++)
{
    new Thread(() =>
    {
        Process.Start("cmd","My Input: " + i);
    }).Start();
}

Does it give you better performance?

Edit: Wait.. Do you need the commands to run one after another?

Yotam Salmon
  • 2,400
  • 22
  • 36
  • No I don't, but the performance bottleneck is all about opening a new cmd window 500 times. – None Jan 29 '17 at 17:54