.Net консольного приложения в трее

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

Я использую .Net 3.5 с c#

6 ответов


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

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


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


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

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