Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

Ответ 6

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