15

Before you say its a duplicate question, please let me explain (as I've read all similar threads).

My application has both of these settings:

  procStartInfo.CreateNoWindow = true;
  procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

and is also has WindowsApplication as the output type.

The black window STILL comes up when I call a command line command. Is there anything else I can do to hide the window? It doesn't happen for all commands, XCOPY is a situation where it the black window does flash up. This only happens though when the destination I'm XCOPYing too already contains the file and it's prompting me if I want to replace it. Even if I pass in /Y it will still flash briefly.

I'm open to using vbscript if that will help, but any other ideas?

The client will call my executable and then pass in a command line command ie:

C:\MyProgram.exe start XCOPY c:\Test.txt c:\ProgramFiles\

Here's the full code of the application:

class Program
{
    static void Main(string[] args)
    {      
            string command = GetCommandLineArugments(args);

            // /c tells cmd that we want it to execute the command that follows and then exit.
            System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c " + command);

            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.UseShellExecute = false;

            // Do not create the black window.
            procStartInfo.CreateNoWindow = true;
            procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo = procStartInfo;
            process.Start();

        }

    private static string GetCommandLineArugments(string[] args)
    {
        string retVal = string.Empty;

        foreach (string arg in args)
            retVal += " " + arg;


        return retVal;
    }
}
mint
  • 3,341
  • 11
  • 38
  • 55
  • Can you post the rest of your `Process`/`ProcessStartInfo` code? – Tim Robinson Aug 09 '10 at 12:50
  • 3
    @fletcher: It's stated in the question that the output type is Windows Application and not console. I've tested it with output type set to Windows app and it works fine. @snow: I'd double check your OutputType setting. – Matt B Aug 09 '10 at 13:06
  • @fletcher That's actually kind of the problem! I would like for the window to not display at all! – mint Aug 09 '10 at 13:06
  • I'm beginning to think this is a bug specific to XCOPY... anyone have any experience with this? – mint Aug 09 '10 at 13:17
  • Ah, my fault. I missed the WinForms part – fletcher Aug 09 '10 at 13:18
  • There are some switches you could try for the XCOPY command. /Q - Does not display file name when copying. /Y - Suppresses prompting to confirm you want to overwrite a file. Maybe you are getting a prompt, but it's being redirected to your STDOUT? – fletcher Aug 09 '10 at 13:25
  • @fletcher Possibly, the black window flashes very quickly with some sort of message but I can't read it because it flashes so fast. Would there be a way to suppress the STDOUT message? – mint Aug 09 '10 at 13:29
  • If you want to try to read the stdout / stderr message, you can redirect it to a string by doing: procStartInfo.RedirectStandardOutput = true; procStartInfo.RedirectStandardError = true; ... string stdout = process.StandardOutput.ReadToEnd(); string stderr = process.StandardError.ReadToEnd(); – James Sulak Aug 09 '10 at 13:38
  • @James They both appear to be empty strings – mint Aug 09 '10 at 13:40

5 Answers5

9

The problem is that you're using cmd.exe. Only its console window will be hidden, not the console window for the process you ask it to start. There's little point in using cmd.exe, unless you are trying to execute some of the commands it implements itself. Like COPY.

You can still suppress the window if you need cmd.exe, you'll have to use the /B option for Start. Type start /? at the command prompt to see options. Not that it helps, you can't use START COPY.

There's a specific quirk in xcopy.exe that might throw you off as well. It does not execute if you don't also redirect the input. It just fails to run without diagnostic.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
5

i see that you are calling cmd and then passing the command as parameters. Instead call the command directly

e.g.

    System.Diagnostics.ProcessStartInfo procStartInfo = new System.DiagnosticsProcessStartInfo("xcopy", "<sourcedir> <destdir> <other parameters>");

procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
ajay_whiz
  • 17,573
  • 4
  • 36
  • 44
  • I probably should have stated this in the question, but the client will pass in whatever command line command he wants to my program, so I cannot hard code xcopy, still repped you though! – mint Aug 09 '10 at 13:45
  • 1
    @Snow, you can still do what he says, `ProcessStartInfo procStartInfo = new ProcessStartInfo(Arg[0], String.Join(" ", Arg.Skip(1).ToArray());` – Scott Chamberlain Aug 09 '10 at 13:53
  • @snow xcopy was just for example – ajay_whiz Aug 09 '10 at 13:55
4

You can try adding

process.StartInfo.UseShellExecute = false; 

to your process

kleopatra
  • 51,061
  • 28
  • 99
  • 211
Andrei C
  • 49
  • 1
  • 2
    Just to clarify the answer. You need `process.StartInfo.UseShellExecute = false;` and `process.StartInfo.CreateNoWindow = false;`. Those two together will hide the process window – Rémi Jul 15 '14 at 14:49
  • 2
    @Rémi: you need `process.StartInfo.CreateNoWindow = true;` – Sjoerd222888 May 04 '15 at 14:25
  • I get the error "The system cannot find the file specified." This is even though I have added the custom command to the system PATH variable. – Najeeb Aug 04 '16 at 19:19
1

If you are calling cmd.exe in your C# code and passing the commands to it via standard input.WriteLine and you don't want your CMD window to pop up every time you run your code, you can simply write this command:

 test.StartInfo.FileName = "cmd.exe";
 test.StartInfo.CreateNoWindow = true;

By setting create no window to false, we are running the command sent to the CMD in the background and the output is not being displayed to the user. By setting it to false, the CMD window pops up.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
chabs
  • 11
  • 2
0

I had a similar task - It is possible to hide the window after creation via an API call. (In your case you maybe need a helper thread.)

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

If you know the handle of the new Window you can call

ShowWindow(hWnd, 0);

0 hides the window, 1 shows the window

To get the handle of the Window take a look at:

pinvoke.net enumwindows(user32)

Cadburry
  • 1,844
  • 10
  • 21