167

Is there a way to hide the console window when executing a console application?

I am currently using a Windows Forms application to start a console process, but I don't want the console window to be displayed while the task is running.

0

10 Answers 10

240

If you wrote the console application you can make it hidden by default.

Create a new console app then then change the "Output Type" type to "Windows Application" (done in the project properties)

Sign up to request clarification or add additional context in comments.

4 Comments

This one gets around issues with ProcessStartInfo where you specify user credentials and that user happens to be logged in or current user. In that situation the CreateNoWindow property is ignored so you always get a console window. By setting the console app to Windows Application but without a window then you get no window.
This one makes a different result to what I am looking for. I want the console window to be minimized but still be there for me to maximize it. With this approach there is no window in the first place.
Note, in VS 2017, it's labeled Windows Forms Application under Application Type.
@KansaiRobot That's what 'hidden' means: not visible. 'Minimized' is what you are looking for.
175

If you are using the ProcessStartInfo class you can set the window style to hidden - in the case of console (not GUI) applications, you have to set CreateNoWindow to true:

System.Diagnostics.ProcessStartInfo start =
      new System.Diagnostics.ProcessStartInfo();
start.FileName = dir + @"\Myprocesstostart.exe";
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; //Hides GUI
start.CreateNoWindow = true; //Hides console

3 Comments

It did not work for invoking a command line tool. Used yourprocess.StartInfo.CreateNoWindow=true; instead, see below.
Doesn't hide the console window, StartInfo.CreateNoWindow = true is required.
This will not hide a console application's console window. The WindowStyle property applies to GUI applications only. This answer, on the other hand, does hide the console window. 120 upvotes (with 2 downvotes) for an answer that doesn't even work? The voting system is in a pathetic state.
69

If you are using Process Class then you can write

yourprocess.StartInfo.UseShellExecute = false;
yourprocess.StartInfo.CreateNoWindow = true;

before yourprocess.start(); and process will be hidden

3 Comments

Good luck if you have to stop that process early. Process.Kill terminates abruptly. Process.CloseMainWindow fails. GenerateConsoleCtrlEvent fails to send ctrl+c or ctrl+break to the process. WM_CLOSE to all thread windows in the process fails. There seems to be no way to cleanly end a process started with those two parameter values. See my question here: stackoverflow.com/questions/16139571/…
@Triynko: You cannot cleanly terminate any process, unless that process actively coöperates. This is not a matter of flags or anything else. There's just nothing in the OS that could trigger a clean shutdown. The common solution here is to use a waitable kernel object, that's signaled in the controlling process, when the slave process should terminate. The slave process needs to actively monitor the state of this waitable object, and initiate clean shutdown once it's signaled.
The child process can also use the parent process as a signal for shutdown (if the child process should not outlive the parent. Pass in the parent PID, use Process.GetProcessById(pid).WaitForExit(...) to wait or poll. Just one option.
22

You can use the FreeConsole API to detach the console from the process :

[DllImport("kernel32.dll")]
static extern bool FreeConsole();

(of course this is applicable only if you have access to the console application's source code)

5 Comments

I wanted to not show the console. While FreeConsole does what its name says, it doesn't prevent Windows from showing the console before it is called.
Then compile the project as a Windows Application, not a Console Application
For the record, this is exactly what I needed, thanks. It also is exactly what the title asks for :) So in the interest of other google voyagers, +1
In addition [DllImport("kernel32.dll")] static extern bool AllocConsole(); allows you to easily run with a console from a standard Win32 application
Works for my .NET Core 2.2 app - if anyone is looking for this specifically.
7

If you're interested in the output, you can use this function:

private static string ExecCommand(string filename, string arguments)
{
    Process process = new Process();
    ProcessStartInfo psi = new ProcessStartInfo(filename);
    psi.Arguments = arguments;
    psi.CreateNoWindow = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.UseShellExecute = false;
    process.StartInfo = psi;

    StringBuilder output = new StringBuilder();
    process.OutputDataReceived += (sender, e) => { output.AppendLine(e.Data); };
    process.ErrorDataReceived += (sender, e) => { output.AppendLine(e.Data); };

    // run the process
    process.Start();

    // start reading output to events
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();

    // wait for process to exit
    process.WaitForExit();

    if (process.ExitCode != 0)
        throw new Exception("Command " + psi.FileName + " returned exit code " + process.ExitCode);

    return output.ToString();
}

It runs the given command line program, waits for it to finish and returns the output as string.

Comments

4

If you're creating a program that doesn't require user input you could always just create it as a service. A service won't show any kind of UI.

2 Comments

But if all you want to do is run the process until it exits, e.g. by calling it from the Task Scheduler, then a service is inconvenient as it continues to exist. In some situations changing the Output Type to Windows Application versus the alternative ProcessWindowStyle as hidden is very convenient.
This answer would be greatly improved by mentioning even a little bit of the process of how to create a service.
4

Add this to your class to import the DLL file:

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

[DllImport("kernel32.dll")] 
static extern IntPtr GetConsoleWindow();

const int SW_HIDE = 0;
const int SW_SHOW = 5;

And then if you want to hide it use this command:

 var handle = GetConsoleWindow();
 ShowWindow(handle, SW_HIDE);

And if you want to show the console:

var handle = GetConsoleWindow();
ShowWindow(handle, SW_SHOW);

1 Comment

[DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("kernel32.dll")] static extern IntPtr GetConsoleWindow(); const int SW_HIDE = 0; const int SW_SHOW = 5;
3

I've got a general solution to share:

using System;
using System.Runtime.InteropServices;

namespace WhateverNamepaceYouAreUsing
{
    class Magician
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    
        const int HIDE = 0;
        const int SHOW = 5;

        public static void DisappearConsole()
        {
            ShowWindow(GetConsoleWindow(), HIDE);
        }
    }
}

Just include this class in your project, and call Magician.DisappearConsole();.

A console will flash when you start the program by clicking on it. When executing from the command prompt, the command prompt disappears very shortly after execution.

I do this for a Discord Bot that runs forever in the background of my computer as an invisible process. It was easier than getting TopShelf to work for me. A couple TopShelf tutorials failed me before I wrote this with some help from code I found elsewhere.

I also tried simply changing the settings in Visual Studio > Project > Properties > Application to launch as a Windows Application instead of a Console Application, and something about my project prevented this from hiding my console - perhaps because DSharpPlus demands to launch a console on startup. I don't know. Whatever the reason, this class allows me to easily kill the console after it pops up.

Comments

1

Based on Adam Markowitz's answer above, following worked for me:

process = new Process();
process.StartInfo = new ProcessStartInfo("cmd.exe", "/k \"" + CmdFilePath + "\"");
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
//process.StartInfo.UseShellExecute = false;
//process.StartInfo.CreateNoWindow = true;
process.Start();

Comments

-1

I know I'm not answering exactly what you want, but I am wondering if you're asking the right question.

Why don't you use either:

  1. windows service
  2. create a new thread and run your process on that

Those sound like better options if all you want is to run a process.

4 Comments

There are plenty of scenarios where launching a utility console application is perfectly legitimate.
In my case a separate process is necessary because of the client/server model that the software I am working on uses.
It doesn't always solve the problem to create a new thread. There are times when you just don't want the annoying window in the background. Also, what if you have a process.start in a loop, then you won't get any work done as console windows pop up in your face.
I launch windowless utility console apps from the Task Scheduler. No need for service, and no parent process from which to fork a thread. These apps write to the EventLog if additional output needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.