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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/751944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:47:02  来源:igfitidea点击:

.Net Console Application in System tray

c#.net-3.5consolesystem-tray

提问by Melursus

Is there a way I can put a console application in the system tray when minimizing ?

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

采纳答案by Sascha

A console has no window to minimize by itself. It runs in a command prompt window. You might hook the window messages and hide the window on minimize. In your application it's possible to add a tray icon just the same as you would do it in a windows application. Well, somehow this smells...

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

But: I'm not sure why you want to do this. A console application is by design different to a windows application. Hence, maybe it's an option to change the app to be a windows form application?

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

回答by TheTXI

You can't hide a console application because it does not actually have a window to hide, seeing as how it is running in the console (the console itself is just a window of the console, not the app running in it)

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

回答by CLaRGe

Yes, you can do this. Create a Windows Forms application and add a NotifyIcon component.

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

Then use the following methods (found on MSDN) to allocate and display a Console

然后使用以下方法(在 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);

When your console is onscreen, capture the minimize button click and use it to hide the console window and update the Notify icon. You can find your window using the following methods (found on MSDN):

当您的控制台在屏幕上时,捕获最小化按钮单击并使用它来隐藏控制台窗口并更新通知图标。您可以使用以下方法(在 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);

Be sure to call FreeConsole whenever you're ready to close the app.

当您准备好关闭应用程序时,请务必调用 FreeConsole。

回答by Boris Gappov

[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);
}

回答by Aron Boyette

I use TrayRunnerfor exactly this purpose. Essentially, it wraps a console application capturing all output. But when minimized, it minimizes to the system tray instead of the task bar. You can even customize what icon to show when minimized. I use it for things like Tomcat or Apache to free up space on my taskbar without running them as Windows Services.

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

回答by Geograph

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               
    }
}