如何让.NET Windows窗体应用程序只在系统托盘中运行?

我需要做什么才能使Windows窗体应用程序能够在系统托盘中运行?

不是一个可以最小化到托盘的应用程序,而是一个只存在于托盘中的应用程序

  • 一个图标
  • 一个工具提示,和
  • 一个“右击"菜单。
233824 次浏览

据我所知,您仍然必须使用表单编写应用程序,但在表单上没有控件,并且永远不会将其设置为可见。使用NotifyIcon(它的MSDN示例可以在在这里中找到)来编写应用程序。

“系统托盘”应用程序只是一个普通的win表单应用程序,唯一的区别是它在windows系统托盘区域创建了一个图标。为了创建sys。托盘图标使用NotifyIcon组件,你可以在工具箱(常用控件)中找到它,并修改它的属性:图标,工具提示。它还允许您处理鼠标单击和双击消息。

还有一件事,为了实现外观和感觉或标准托盘应用程序。添加followinf行在你的主窗体显示事件:

private void MainForm_Shown(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
Hide();
}

正如mat1t所说,你需要在你的应用程序中添加一个NotifyIcon,然后使用下面的代码来设置工具提示和上下文菜单:

this.notifyIcon.Text = "This is the tooltip";
this.notifyIcon.ContextMenu = new ContextMenu();
this.notifyIcon.ContextMenu.MenuItems.Add(new MenuItem("Option 1", new EventHandler(handler_method)));

这段代码只显示了系统托盘中的图标:

this.notifyIcon.Visible = true;  // Shows the notify icon in the system tray

如果你有一个表格(无论出于什么原因),以下将是需要的:

this.ShowInTaskbar = false;  // Removes the application from the taskbar
Hide();

右键点击获得上下文菜单是自动处理的,但如果你想在左键点击上做一些操作,你需要添加一个点击处理程序:

    private void notifyIcon_Click(object sender, EventArgs e)
{
var eventArgs = e as MouseEventArgs;
switch (eventArgs.Button)
{
// Left click to reactivate
case MouseButtons.Left:
// Do your stuff
break;
}
}
我已经用。net 1.1写了一个traybar应用程序,我不需要表单 首先,将项目的启动对象设置为在模块中定义的Sub Main 然后以编程方式创建组件:NotifyIconContextMenu.
. 0 请确保包含MenuItem“Quit”或类似内容 将ContextMenu绑定到NotifyIcon 调用Application.Run()。< br > 在Quit MenuItem的事件处理程序中,请确保调用集合NotifyIcon.Visible = False,然后调用Application.Exit()。 将你需要的添加到ContextMenu并正确处理:)

  1. 使用向导创建一个新的Windows应用程序。
  2. 从代码中删除Form1
  3. 删除Program.cs中启动Form1. c的代码。
  4. 使用NotifyIcon类创建你的系统托盘图标(给它分配一个图标)。
  5. 添加一个上下文菜单。
  6. 或者对NotifyIcon的鼠标点击做出反应,并区分右键和左键点击,设置你的上下文菜单,并显示哪个按钮(右/左)被按下。
  7. Application.Run()来保持应用程序运行,Application.Exit()退出。或者bool bRunning = true; while(bRunning){Application.DoEvents(); Thread.Sleep(10);}。然后设置bRunning = false;退出应用程序。

下面是我如何用Visual  Studio  2010年, .NET 4做到这一点

  1. 创建一个Windows窗体应用程序,在属性中设置“单个实例应用程序”
  2. 添加一个上下文菜单
  3. 在上下文菜单条中添加一些条目,双击它们以获取处理程序,例如'exit'(双击)-> handler -> me.Close()
  4. 添加一个NotifyIcon,在设计器set contextMenuStrip中,选择一个图标(你可以在VisualStudio文件夹中'common7…'下找到一些图标)
  5. 在设计器中为窗体设置属性:FormBorderStyle:none, ShowIcon:false, ShowInTaskbar:false,不透明度:0%,WindowState:最小化
  6. <李>添加我。Visible=false在Form1_Load的末尾,这将隐藏图标时 使用Ctrl + 选项卡
  7. 运行并根据需要进行调整。

代码项目文章创建任务托盘应用给出了一个非常简单的解释和创建只存在于系统托盘中的应用程序的例子。

基本上改变Program.cs中的Application.Run(new Form1());行来启动一个继承自ApplicationContext的类,并让该类的构造函数初始化一个NotifyIcon

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);


Application.Run(new MyCustomApplicationContext());
}
}




public class MyCustomApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;


public MyCustomApplicationContext ()
{
// Initialize Tray Icon
trayIcon = new NotifyIcon()
{
Icon = Resources.AppIcon,
ContextMenu = new ContextMenu(new MenuItem[] {
new MenuItem("Exit", Exit)
}),
Visible = true
};
}


void Exit(object sender, EventArgs e)
{
// Hide tray icon, otherwise it will remain shown until user mouses over it
trayIcon.Visible = false;


Application.Exit();
}
}

这是一个非常友好的框架通知区域应用程序…将NotificationIcon添加到基本表单并将自动生成的代码更改为下面的代码就足够了:

public partial class Form1 : Form
{
private bool hidden = false;


public Form1()
{
InitializeComponent();
}


private void Form1_Load(object sender, EventArgs e)
{
this.ShowInTaskbar = false;
//this.WindowState = FormWindowState.Minimized;
this.Hide();
hidden = true;
}


private void notifyIcon1_Click(object sender, EventArgs e)
{
if (hidden) // this.WindowState == FormWindowState.Minimized)
{
// this.WindowState = FormWindowState.Normal;
this.Show();
hidden = false;
}
else
{
// this.WindowState = FormWindowState.Minimized;
this.Hide();
hidden = true;
}
}
}

简单的添加

this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;

到你的表单对象。 你只会在系统托盘上看到一个图标

notifyIcon1->ContextMenu = gcnew


System::Windows::Forms::ContextMenu();
System::Windows::Forms::MenuItem^ nIItem = gcnew
System::Windows::Forms::MenuItem("Open");


nIItem->Click += gcnew System::EventHandler(this, &your_class::Open_NotifyIcon);


notifyIcon1->ContextMenu->MenuItems->Add(nIItem);

您可以创建表单,修改它,然后将它作为参数传递给Application.Run。:

    internal static class Program
{
/// <summary>
///  The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
var form = new Form1();
form.Hide();
form.Opacity = 0;
form.ShowInTaskbar = false;
Application.Run(form);
}
}

在设计时将你的NotifyIconContextMenu(如果需要)作为常规应用程序添加到你的表单中。确保你的NotifyiconVisible,并有一个相关的图标。这还将允许您使用以后可能出于任何原因需要的表单

我将公认的答案改编为。net Core,使用建议更换来处理弃用的类:

  • 快捷菜单→ContextMenuStrip
  • 子菜单→ToolStripMenuItem

Program.cs

namespace TrayOnlyWinFormsDemo
{
internal static class Program
{
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new MyCustomApplicationContext());
}
}
}

MyCustomApplicationContext.cs

using TrayOnlyWinFormsDemo.Properties;  // Needed for Resources.AppIcon


namespace TrayOnlyWinFormsDemo
{
public class MyCustomApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;


public MyCustomApplicationContext()
{
trayIcon = new NotifyIcon()
{
Icon = Resources.AppIcon,
ContextMenuStrip = new ContextMenuStrip()
{
Items = { new ToolStripMenuItem("Exit", null, Exit) }
},
Visible = true
};
}


void Exit(object? sender, EventArgs e)
{
trayIcon.Visible = false;
Application.Exit();
}
}
}

在。net 6中,我必须像这样工作我的类的核心:

private NotifyIcon trayIcon;
private ContextMenuStrip contextMenu1;
private ToolStripMenuItem menuItem1;


public MyCustomApplicationContext()
{
contextMenu1 = new System.Windows.Forms.ContextMenuStrip();
menuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.menuItem1.Text = "E&xit";
this.menuItem1.Click += new System.EventHandler(Exit);
this.contextMenu1.Items.AddRange(
new System.Windows.Forms.ToolStripMenuItem[] {this.menuItem1 });
trayIcon = new NotifyIcon(){Icon = Resources.AppIcon, ContextMenuStrip = this.contextMenu1, Visible = true };


}