C#
console application
console window
hide console
show console

Show/Hide the console window of a C console application

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, you can show or hide the console window at runtime using the Windows API functions ShowWindow and GetConsoleWindow via P/Invoke. This is useful for background services, system tray applications, or programs that should run without a visible console. You can also set the project output type to "Windows Application" to hide the console by default at startup, then show it programmatically when needed.

Using P/Invoke to Show/Hide

csharp
1using System;
2using System.Runtime.InteropServices;
3
4class Program
5{
6    [DllImport("kernel32.dll")]
7    static extern IntPtr GetConsoleWindow();
8
9    [DllImport("user32.dll")]
10    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
11
12    const int SW_HIDE = 0;
13    const int SW_SHOW = 5;
14    const int SW_MINIMIZE = 6;
15    const int SW_RESTORE = 9;
16
17    static void Main()
18    {
19        var handle = GetConsoleWindow();
20
21        // Hide the console window
22        ShowWindow(handle, SW_HIDE);
23
24        // Do background work...
25        System.Threading.Thread.Sleep(3000);
26
27        // Show it again
28        ShowWindow(handle, SW_SHOW);
29
30        Console.WriteLine("Console is visible again!");
31        Console.ReadLine();
32    }
33}

GetConsoleWindow() returns the handle to the console window associated with the current process. ShowWindow() changes its visibility state.

Helper Class

Wrap the P/Invoke calls in a reusable class:

csharp
1public static class ConsoleWindow
2{
3    [DllImport("kernel32.dll")]
4    private static extern IntPtr GetConsoleWindow();
5
6    [DllImport("user32.dll")]
7    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
8
9    private const int SW_HIDE = 0;
10    private const int SW_SHOW = 5;
11    private const int SW_MINIMIZE = 6;
12
13    private static readonly IntPtr Handle = GetConsoleWindow();
14
15    public static void Hide() => ShowWindow(Handle, SW_HIDE);
16    public static void Show() => ShowWindow(Handle, SW_SHOW);
17    public static void Minimize() => ShowWindow(Handle, SW_MINIMIZE);
18
19    public static bool IsVisible
20    {
21        get
22        {
23            // IsWindowVisible returns true if the window is visible
24            return IsWindowVisible(Handle);
25        }
26    }
27
28    [DllImport("user32.dll")]
29    private static extern bool IsWindowVisible(IntPtr hWnd);
30}
31
32// Usage
33ConsoleWindow.Hide();
34// ... background work ...
35ConsoleWindow.Show();

Hide Console at Startup (Project Setting)

Change the project output type to suppress the console window from the start:

xml
1<!-- In your .csproj file -->
2<PropertyGroup>
3    <OutputType>WinExe</OutputType>  <!-- Instead of 'Exe' -->
4</PropertyGroup>

Or in Visual Studio: Project Properties > Application > Output Type > Windows Application.

With WinExe, no console window appears at startup. You can still use Console.WriteLine() — the output goes nowhere unless you allocate a console:

csharp
1[DllImport("kernel32.dll")]
2static extern bool AllocConsole();
3
4[DllImport("kernel32.dll")]
5static extern bool FreeConsole();
6
7static void Main()
8{
9    // No console visible (WinExe)
10
11    // Allocate a console when needed
12    AllocConsole();
13    Console.WriteLine("Now I have a console!");
14    Console.ReadLine();
15    FreeConsole();
16}

System Tray Application with Hidden Console

A common pattern is to hide the console and show a system tray icon:

csharp
1using System;
2using System.Drawing;
3using System.Windows.Forms;
4using System.Runtime.InteropServices;
5
6class TrayApp
7{
8    [DllImport("kernel32.dll")]
9    static extern IntPtr GetConsoleWindow();
10
11    [DllImport("user32.dll")]
12    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
13
14    static NotifyIcon trayIcon;
15
16    static void Main()
17    {
18        // Hide console
19        ShowWindow(GetConsoleWindow(), 0);
20
21        // Create tray icon
22        trayIcon = new NotifyIcon
23        {
24            Icon = SystemIcons.Application,
25            Text = "My Background App",
26            Visible = true,
27            ContextMenuStrip = new ContextMenuStrip()
28        };
29
30        trayIcon.ContextMenuStrip.Items.Add("Show Console", null, (s, e) =>
31            ShowWindow(GetConsoleWindow(), 5));
32        trayIcon.ContextMenuStrip.Items.Add("Exit", null, (s, e) =>
33            Application.Exit());
34
35        Application.Run();
36    }
37}

Redirecting Console Output

When the console is hidden, you may want to redirect output to a file:

csharp
1using System.IO;
2
3// Redirect Console.WriteLine to a log file
4var writer = new StreamWriter("app.log", append: true) { AutoFlush = true };
5Console.SetOut(writer);
6Console.SetError(writer);
7
8Console.WriteLine("This goes to app.log, not the hidden console");

.NET Generic Host (Modern Approach)

For background services in .NET 6+, use the Generic Host instead of hiding a console:

csharp
1using Microsoft.Extensions.Hosting;
2
3var builder = Host.CreateApplicationBuilder(args);
4builder.Services.AddHostedService<MyBackgroundService>();
5var host = builder.Build();
6host.Run();
7
8class MyBackgroundService : BackgroundService
9{
10    protected override async Task ExecuteAsync(CancellationToken ct)
11    {
12        while (!ct.IsCancellationRequested)
13        {
14            // Do work
15            await Task.Delay(1000, ct);
16        }
17    }
18}

This runs as a proper service without any console window and can be deployed as a Windows Service with UseWindowsService().

Common Pitfalls

  • Windows-only APIs: GetConsoleWindow, ShowWindow, AllocConsole, and FreeConsole are Windows-specific. They do not work on Linux or macOS. For cross-platform apps, use .NET Generic Host for background services instead.
  • GetConsoleWindow returning IntPtr.Zero: If the process has no console (e.g., started as a Windows Service or with WinExe output type), GetConsoleWindow() returns IntPtr.Zero. Check for this before calling ShowWindow().
  • Console.ReadLine blocking after hide: If the console is hidden while Console.ReadLine() is waiting, the application hangs because the user cannot type. Cancel or skip input reads before hiding.
  • Multiple calls to AllocConsole: AllocConsole() fails if a console is already attached. Call FreeConsole() first if you need to reallocate, or check the return value of GetConsoleWindow().
  • Flash of console window at startup: With OutputType=Exe, the console briefly appears before ShowWindow(handle, SW_HIDE) runs. Use OutputType=WinExe and AllocConsole() only when needed to avoid the flash.

Summary

  • Use GetConsoleWindow() and ShowWindow() via P/Invoke to show/hide the console at runtime
  • Set OutputType to WinExe in the .csproj to prevent the console from appearing at startup
  • Use AllocConsole() to create a console window on demand for WinExe applications
  • Redirect Console.SetOut() to a file when the console is hidden to preserve log output
  • For modern .NET background services, use Host.CreateApplicationBuilder with BackgroundService instead of hiding a console window
  • These APIs are Windows-only — use cross-platform alternatives for Linux/macOS deployment

Course illustration
Course illustration

All Rights Reserved.