Hide Command Window in C# Application
Asked Answered
A

5

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;
    }
}
Anastasius answered 9/8, 2010 at 12:47 Comment(9)
Can you post the rest of your Process/ProcessStartInfo code?Vanthe
@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.Gusman
@fletcher That's actually kind of the problem! I would like for the window to not display at all!Anastasius
I'm beginning to think this is a bug specific to XCOPY... anyone have any experience with this?Anastasius
Ah, my fault. I missed the WinForms partDauphine
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?Dauphine
@Dauphine 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?Anastasius
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();Bauske
@James They both appear to be empty stringsAnastasius
L
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.

Lakes answered 9/8, 2010 at 14:11 Comment(1)
the /B worked for the xcopy command, that might be all we need to be honest.Anastasius
P
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;
Pulverize answered 9/8, 2010 at 13:42 Comment(3)
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!Anastasius
@Snow, you can still do what he says, ProcessStartInfo procStartInfo = new ProcessStartInfo(Arg[0], String.Join(" ", Arg.Skip(1).ToArray());Luna
@snow xcopy was just for examplePulverize
I
4

You can try adding

process.StartInfo.UseShellExecute = false; 

to your process

Invidious answered 14/11, 2012 at 17:55 Comment(3)
Just to clarify the answer. You need process.StartInfo.UseShellExecute = false; and process.StartInfo.CreateNoWindow = false;. Those two together will hide the process windowPluto
@Rémi: you need process.StartInfo.CreateNoWindow = true;Accessible
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.Tien
I
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.

Indene answered 19/5, 2022 at 20:34 Comment(0)
C
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)

Chemush answered 4/5, 2015 at 15:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.