Консольное приложение .Net в системном трее - PullRequest
12 голосов
/ 15 апреля 2009

Есть ли способ положить консольное приложение в системный трей при сворачивании?

Ответы [ 6 ]

21 голосов
/ 15 апреля 2009

Да, вы можете сделать это. Создайте приложение Windows Forms и добавьте компонент 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, когда будете готовы закрыть приложение.

8 голосов
/ 15 апреля 2009

Консоль не имеет окна для минимизации. Он запускается в окне командной строки. Вы можете перехватить сообщения окна и скрыть окно при сворачивании. В вашем приложении можно добавить иконку в трее точно так же, как в приложении для Windows. Ну, как-то это пахнет ...

Но: я не уверен, почему ты хочешь это сделать. Консольное приложение по дизайну отличается от Windows-приложения. Следовательно, может быть, это вариант, чтобы изменить приложение на приложение формы Windows?

6 голосов
/ 04 июня 2017
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               
    }
}
3 голосов
/ 15 апреля 2016

Я использую TrayRunner именно для этой цели. По сути, это обертка консольного приложения, фиксирующая весь вывод. Но при свертывании сворачивается в системный трей вместо панели задач. Вы даже можете настроить, какой значок показывать при сворачивании. Я использую его для таких вещей, как Tomcat или Apache, чтобы освободить место на моей панели задач без запуска их в качестве служб Windows.

1 голос
/ 06 августа 2012
[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);
}
0 голосов
/ 15 апреля 2009

Вы не можете скрыть консольное приложение, потому что на самом деле у него нет окна, которое нужно скрыть, видя, как оно работает в консоли (сама консоль - это просто окно консоли, а не приложение, работающее в ней)

...