How can I hide a console window?
Solution 1
If you don't need the console (e.g. for Console.WriteLine
) then change the applications build options to be a Windows application.
This changes a flag in the .exe
header so Windows doesn't allocate a console session when the application starts.
Solution 2
If I understand your question, just create the console process manually and hide the console window:
Process process = new Process();
process.StartInfo.FileName = "Bogus.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
I do this for an WPF app which executes a console app (in a background worker) and redirects standard output so you can display the result in a window if needed. Works a treat so let me know if you need to see more code (worker code, redirection, argument passing, etc.)
Solution 3
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);
// see the comment below
private enum StdHandle
{
StdIn = -10,
StdOut = -11,
StdErr = -12
};
void HideConsole()
{
var ptr = GetStdHandle((int)StdHandle.StdOut);
if (!CloseHandle(ptr))
throw new Win32Exception();
ptr = IntPtr.Zero;
if (!FreeConsole())
throw new Win32Exception();
}
See more console-related API calls here
Solution 4
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("kernel32")]
public static extern IntPtr GetConsoleWindow();
[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
static void Main(string[] args)
{
IntPtr hConsole = GetConsoleWindow();
if (IntPtr.Zero != hConsole)
{
ShowWindow(hConsole, 0);
}
}
This should do what your asking.
Stefan Steiger
I'm an avid HTTP-header-reader, github-user and a few more minor things like BusinessIntelligence & Web Software Developer Technologies I work with: Microsoft Reporting- & Analysis Service (2005-2016), ASP.NET, ASP.NET MVC, .NET Core, ADO.NET, JSON, XML, SOAP, Thrift ActiveDirectory, OAuth, MS Federated Login XHTML5, JavaScript (jQuery must die), ReverseAJAX/WebSockets, WebGL, CSS3 C#, .NET/mono, plain old C, and occasional C++ or Java and a little Bash-Scripts, Python and PHP5 I have a rather broad experience with the following relational SQL databases T-SQL PL/PGsql including CLR / extended stored procedures/functions Occasionally, I also work with MySQL/MariaDB Firebird/Interbase Oracle 10g+ SqLite Access I develop Enterprise Web-Applications (.NET 2.0 & 4.5) and interface to systems like LDAP/AD (ActiveDirectory) WebServices (including WCF, SOAP and Thrift) MS Federated Login OAuth DropBox XML & JSON data-stores DWG/SVG imaging for architecture In my spare-time, I'm a Linux-Server-Enthusiast (I have my own Web & DNS server) and reverse-engineer with interest in IDS Systems (IntrusionDetection), WireShark, IDA Pro Advanced, GDB, libPCAP. - Studied Theoretical Physics at the Swiss Federal Institute of Technology (ETHZ).
Updated on May 15, 2020Comments
-
Stefan Steiger about 4 years
Question: I have a console program that shouldn't be seen. (It resets IIS and deletes temp files.)
Right now I can manage to hide the window right after start like this:
static void Main(string[] args) { var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); Console.WriteLine(currentProcess.MainWindowTitle); IntPtr hWnd = currentProcess.MainWindowHandle;//FindWindow(null, "Your console windows caption"); //put your console window caption here if (hWnd != IntPtr.Zero) { //Hide the window ShowWindow(hWnd, 0); // 0 = SW_HIDE }
The problem is this shows the window for a blink of a second. Is there any constructor for a console program, where I can hide the window before it is shown?
And second:
I use
[System.Runtime.InteropServices.DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
and I don't like the 32 in it. Is there any way to do this without DllImport ?
A .NET way ? -
Andreas Rejbrand over 13 years@Si: I think that the OP want to be able to start the "no-window console program" by double-clicking it, for example, not necessarily programmatically from another program.
-
Grant Crofton over 13 yearsOr make it a windows service, although that will have a different lifecycle
-
abatishchev over 13 yearsCreate a Windows app and don't create a Windows form
-
Dirk Vollmar over 13 yearsNote that instead of
throw new PInvokeExcpetion()
normallythrow new Win32Exception()
orthrow Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
is sufficient. WithWin32Exception()
you don't have to bother callingGetLastError
yourself and then mapping the error code to a meaningful message. Everything is already done for you. -
Dirk Vollmar over 13 years@Grand Crofton: Services are for a long-running or repeating background tasks, not for user-triggered actions like an IIS reset. So a service doesn't seem appropriate here. Unless you want to reset IIS every 5 minutes or so, of course ;-)
-
Michael Baldry over 13 years@0xA3: repeating background tasks should not be implemented as a service but as a scheduled task. Having a service running forever when it only actually does something every few mins is a waste of memory, cpu time, coding time (writing a service is a lot more complicated than a console application) and maintainence. Also if you have a memory leak, it'll grow over time in a service, in a scheduled task once the task is finished the process is killed, so it has little effect.
-
Stefan Steiger over 13 yearslol, works. Just out of interest, if I would want to show the console again [when it is a window application], how would I do that ? ( I mean apart from switching back to console application)
-
Richard over 13 years@Quandary: The Win32 API
AllocConsole
will create a console window for a process without one. But it isn't clear ifConsole.Out
etc. would be hooked up automatically or you would need to useConsole.OpenStandardOutput
etc. -
si618 over 13 yearsTrue, I wasn't sure and have had the same need before. One thing I haven't be able to capture is coloured ANSI console output into WPF. See stackoverflow.com/questions/1529254/…
-
Bostwick about 9 yearsYou really should have included GetStdHandle in your example (I used an enum to make it clear what the int's are instead of just using the -11..) ** private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 }; private static extern IntPtr GetStdHandle(StdHandle std); **
-
abatishchev about 9 years@Bostwick: Updated from here. Thanks!