显示/隐藏c#控制台应用程序的控制台窗口

我在谷歌上搜索如何隐藏自己的控制台窗口的信息。令人惊讶的是,我能找到的唯一解决方案是涉及FindWindow()来找到控制台窗口从标题来看的hack解决方案。我深入研究了一下Windows API,发现有一种更好更简单的方法,所以我想把它贴在这里,让其他人找到。

如何隐藏(并显示)与我自己的c#控制台应用程序相关联的控制台窗口?

274335 次浏览

方法如下:

using System.Runtime.InteropServices;

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


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


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

var handle = GetConsoleWindow();


// Hide
ShowWindow(handle, SW_HIDE);


// Show
ShowWindow(handle, SW_SHOW);

只需转到应用程序的属性并将输出类型控制台应用程序更改为Windows应用程序

如果想隐藏控制台本身,为什么还需要控制台应用程序呢?=)

我建议将项目输出类型设置为Windows应用程序而不是控制台应用程序。它不会显示控制台窗口,而是像控制台应用程序一样执行所有操作。

请看我的帖子:

显示Windows应用程序中的控制台

您可以创建一个Windows应用程序(带或不带窗口)并根据需要显示控制台。使用此方法,控制台窗口永远不会出现,除非显式地显示它。我将它用于双模式应用程序,我想在控制台或gui模式下运行,这取决于它们是如何打开的。

如果你不想依赖于窗口标题,请使用以下方法:

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

...

    IntPtr h = Process.GetCurrentProcess().MainWindowHandle;
ShowWindow(h, 0);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormPrincipale());

如果你在集成一个小批处理应用程序时没有问题,有一个名为Cmdow.exe的程序,它将允许你根据控制台标题隐藏控制台窗口

Console.Title = "MyConsole";
System.Diagnostics.Process HideConsole = new System.Diagnostics.Process();
HideConsole.StartInfo.UseShellExecute = false;
HideConsole.StartInfo.Arguments = "MyConsole /hid";
HideConsole.StartInfo.FileName = "cmdow.exe";
HideConsole.Start();

将exe添加到解决方案中,将构建操作设置为“Content”,将Copy设置为适合您的输出目录,并且cmdow在运行时将隐藏控制台窗口。

要使控制台再次可见,只需更改Arguments

HideConsole.StartInfo.Arguments = "MyConsole /Vis";

你可以做相反的操作,将应用程序输出类型设置为:Windows Application。然后将此代码添加到应用程序的开头。

[DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetStdHandle(int nStdHandle);


[DllImport("kernel32.dll", EntryPoint = "AllocConsole", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int AllocConsole();


private const int STD_OUTPUT_HANDLE = -11;
private const int MY_CODE_PAGE = 437;
private static bool showConsole = true; //Or false if you don't want to see the console


static void Main(string[] args)
{
if (showConsole)
{
AllocConsole();
IntPtr stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
Microsoft.Win32.SafeHandles.SafeFileHandle safeFileHandle = new Microsoft.Win32.SafeHandles.SafeFileHandle(stdHandle, true);
FileStream fileStream = new FileStream(safeFileHandle, FileAccess.Write);
System.Text.Encoding encoding = System.Text.Encoding.GetEncoding(MY_CODE_PAGE);
StreamWriter standardOutput = new StreamWriter(fileStream, encoding);
standardOutput.AutoFlush = true;
Console.SetOut(standardOutput);
}


//Your application code
}

如果showConsoletrue,此代码将显示控制台

“只是为了隐藏”你可以:

将输出类型从< em > < / em >控制台应用程序更改为< em > Windows应用程序< / em >

而不是Console.Readline/key,你可以在结尾使用new ManualResetEvent(false).WaitOne()来保持应用程序运行。

根据Timwi的回答,我已经创建了一个helper类来包装所需的代码:

using System;
using System.Runtime.InteropServices;
static class ConsoleExtension {
const int SW_HIDE = 0;
const int SW_SHOW = 5;
readonly static IntPtr handle = GetConsoleWindow();
[DllImport("kernel32.dll")] static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd,int nCmdShow);


public static void Hide() {
ShowWindow(handle,SW_HIDE); //hide the console
}
public static void Show() {
ShowWindow(handle,SW_SHOW); //show the console
}
}