0

I have been trying to open 2 CMD windows, but once I open the 2nd CMD window it just uses the 1st CMD window.

I tried duplicating the below code and using p2, and info2 so it would create a whole new cmd window, but it didn't help.

Console.BackgroundColor = ConsoleColor.DarkGreen;
Console.Title = "PCRF";

Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.UseShellExecute = false;

p.StartInfo = info;
p.Start();

using (StreamWriter sw = p.StandardInput)
{
    if (sw.BaseStream.CanWrite)
    {
        sw.WriteLine("cd " + tbFilePath.Text + "\\SW\\bin\\Apps\\PCRFServer_new ");
        sw.WriteLine("runServer.bat " + ip_res  + userSelectedPcrfFilePath);       
    }
}
Illidanek
  • 996
  • 1
  • 18
  • 32
Tal Soreq
  • 1
  • 1
  • 1
    It would be nice to see the p2 code so we can see if you've copied it completely. – Ryanas Aug 19 '14 at 10:49
  • Where's the code that tries to open two consoles? – Panagiotis Kanavos Aug 19 '14 at 10:49
  • Don't forget to dispose the process after you're done: `using (System.Diagnostics.Process process = new System.Diagnostics.Process())` – dbc Aug 19 '14 at 10:53
  • Possible Duplicate? [Open two console windows from C#](http://stackoverflow.com/questions/3379022/open-two-console-windows-from-c-sharp) – Izzy Aug 19 '14 at 10:58

1 Answers1

0

You can run multiple instances of cmd.exe as detached processes with redirected input and/or output from within a c# program. You cannot, however, create multiple console windows for them straightforwardly and still redirect the input or output back to yourself.

By default, whenever a windows process creates a child process, it inherits the console window of the parent, if any. From Process Creation Flags:

CREATE_NEW_CONSOLE 0x00000010

The new process has a new console, instead of inheriting its parent's console (the default). For more information, see Creation of a Console.

And from Creation of a Console:

The system creates a new console when it starts a console process, a character-mode process whose entry point is the main function. For example, the system creates a new console when it starts the command processor. When the command processor starts a new console process, the user can specify whether the system creates a new console for the new process or whether it inherits the command processor's console.

A process can create a console by using one of the following methods:

  • A GUI or console process can use the CreateProcess function with CREATE_NEW_CONSOLE to create a console process with a new console. (By default, a console process inherits its parent's console, and there is no guarantee that input is received by the process for which it was intended.)
  • A graphical user interface (GUI) or console process that is not currently attached to a console can use the AllocConsole function to create a new console. (GUI processes are not attached to a console when they are created. Console processes are not attached to a console if they are created using CreateProcess with DETACHED_PROCESS.)

Unfortunately, the Process class does not expose the CREATE_NEW_CONSOLE functionality, as can be seen from the reference source.

I will note that your code does successfully create two cmd.exe processes that, while sharing the same console window, have different input streams and can both be used to execute batch files in parallel. I tested this with the following code, and was able to see multiple instances of cmd.exe running in the Windows Task Manager, each doing its appointed task:

    private static void TestMultipleCmdLaunches()
    {
        TestCmdLaunch("cmd.exe", GetNextColorCommand(), "title PCRF", "echo window 1", "sleep 60");
        TestCmdLaunch("cmd.exe", GetNextColorCommand(), "title PCRF", "echo window 2", "sleep 60");
        TestCmdLaunch("cmd.exe", GetNextColorCommand(), "title PCRF", "yes 1");
        TestCmdLaunch("cmd.exe", GetNextColorCommand(), "title PCRF", "yes 2");
    }

    static string[] backgroundColors = 
        { "0F","1F","2F","3F","4F", "5F", "60", "70", "8F", "90", "A0", "B0", "C0", "D0", "E0"};
    static int lastBackgroundColor = 0;
    private static string GetNextColorCommand()
    {
        int nextColor = unchecked(Interlocked.Increment(ref lastBackgroundColor) % backgroundColors.Length);
        return "color " + backgroundColors[nextColor];
    }

    private static void TestCmdLaunch(string filename, params string [] commands)
    {
        using (Process p = new Process())
        {
            ProcessStartInfo info = new ProcessStartInfo();
            info.FileName = filename;
            info.RedirectStandardInput = true;
            info.UseShellExecute = false;

            p.StartInfo = info;
            p.Start();

            using (StreamWriter sw = p.StandardInput)
            {
                if (sw.BaseStream.CanWrite)
                {
                    foreach (var cmd in commands)
                    {
                        sw.WriteLine(cmd);
                    }
                }
            }
        }
    }

The only problem is that the outputs appear intermingled in the console window. Perhaps you want to redirect the output back to your own process anyway?

dbc
  • 104,963
  • 20
  • 228
  • 340