系统托盘中的.Net控制台应用程序

有没有办法在最小化时将控制台应用程序放在系统托盘中?

我使用.Net 3.5和c#

控制台没有窗口可以自行最小化。 它在命令提示符窗口中运行。 您可以挂钩窗口消息并在最小化时隐藏窗口。 在您的应用程序中,可以添加托盘图标,就像在Windows应用程序中一样。 好吧,不知怎的,这闻起来 ……

但是:我不确定你为什么要这样做。 控制台应用程序的设计与Windows应用程序不同。 因此,也许可以选择将应用程序更改为Windows窗体应用程序?

是的,你可以这样做。 创建Windows窗体应用程序并添加NotifyIcon组件 。

然后使用以下方法( 在MSDN上找到 )分配和显示控制台

[DllImport("kernel32.dll")] public static extern Boolean AllocConsole(); [DllImport("kernel32.dll")] public static extern Boolean FreeConsole(); [DllImport("kernel32.dll")] public static extern Boolean AttachConsole(Int32 ProcessId); 

当您的控制台在屏幕上时,捕获最小化按钮单击并使用它来隐藏控制台窗口并更新“通知”图标。 您可以使用以下方法找到您的窗口( 在MSDN上找到 ):

 [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); // Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter. // Also consider whether you're being lazy or not. [DllImport("user32.dll", EntryPoint="FindWindow", SetLastError = true)] static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); 

每当您准备关闭应用程序时,请务必致电FreeConsole。

 using System.Windows.Forms; using System.Drawing; static NotifyIcon notifyIcon = new NotifyIcon(); static bool Visible = true; static void Main(string[] args) { notifyIcon.DoubleClick += (s, e) => { Visible = !Visible; SetConsoleWindowVisibility(Visible); }; notifyIcon.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); notifyIcon.Visible = true; notifyIcon.Text = Application.ProductName; var contextMenu = new ContextMenuStrip(); contextMenu.Items.Add("Exit", null, (s, e) => { Application.Exit(); }); notifyIcon.ContextMenuStrip = contextMenu; Console.WriteLine("Running!"); // Standard message loop to catch click-events on notify icon // Code after this method will be running only after Application.Exit() Application.Run(); notifyIcon.Visible = false; } [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); public static void SetConsoleWindowVisibility(bool visible) { IntPtr hWnd = FindWindow(null, Console.Title); if (hWnd != IntPtr.Zero) { if (visible) ShowWindow(hWnd, 1); //1 = SW_SHOWNORMAL else ShowWindow(hWnd, 0); //0 = SW_HIDE } } 

我正是将TrayRunner用于此目的。 本质上,它包装了一个捕获所有输出的控制台应用程序。 但是当最小化时,它最小化到系统托盘而不是任务栏。 您甚至可以自定义最小化时要显示的图标。 我将它用于Tomcat或Apache之类的东西,以释放我的任务栏上的空间,而无需将它们作为Windows服务运行。

 [DllImport("user32.dll")] internal static extern bool SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, Int32 lParam); static Int32 WM_SYSCOMMAND = 0x0112; static Int32 SC_MINIMIZE = 0x0F020; static void Main(string[] args) { SendMessage(Process.GetCurrentProcess().MainWindowHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0); } 

您无法隐藏控制台应用程序,因为它实际上没有要隐藏的窗口,看它是如何在控制台中运行的(控制台本身只是控制台的一个窗口,而不是在其中运行的应用程序)