如何制作仅在系统托盘中运行的.NET Windows窗体应用程序?


216

要使Windows Forms应用程序在系统托盘中运行,我需要做什么?

不是只能最小化托盘的应用程序,而是仅存在于托盘中的应用程序,仅包含图标,工具提示和“右键单击”菜单。



9
大多数答案中都缺少一些内容-不要忘记设置icon.Visible = false,然后Dispose()退出应用程序时显示图标。否则,程序退出后您仍然会看到该图标。经过几次测试后,您将不再知道哪个图标是真实的。
Tomasz

如果您是采用更现代的WPF方法,则可以尝试以下方法:codeproject.com/Articles/36788/…–
Murray Foxcroft,

Answers:


85

代码项目文章“ 创建任务托盘应用程序”给出了一个非常简单的说明,并举例说明了创建仅存在于系统托盘中的应用程序。

基本上,改Application.Run(new Form1());线Program.cs,而不是启动一个类继承自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();
    }
}

13
这是一个很好的起点。请注意,“ AppIcon”必须是使用“项目->属性->资源->添加资源”添加的资源名称,然后重新编译该项目。
Lavamantis

1
我做了properties..resources..add resource..icon ..重新编译,仍然得到“错误CS0103名称'Resources'在当前上下文中不存在”
barlop

@barlop我必须这样写:Properites.Resources.AppIcon
Simon Perepelitsa

@SimonPerepelitsa谢谢,我不确定我在实验中做了什么,我想评论的是有效的方法,但是我一定忘记了我所做的某些方法。但是最终,我使用的方法是从可以拖动的东西面板中拖动通知图标。然后在表单上单击它,单击一个小箭头,这会弹出一个菜单来选择它的图标!
barlop

17

正如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();

右键单击以获取上下文菜单是自动处理的,但是如果要对左键单击执行某些操作,则需要添加Click处理程序:

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

15

我已经用.NET 1.1编写了一个traybar应用程序,不需要表单。
首先,将项目的启动对象设置为Sub Main,在模块中定义。
然后以编程方式创建组件:NotifyIconContextMenu
确保包括MenuItem“退出”或类似内容。
将绑定ContextMenuNotifyIcon
调用Application.Run()
在退出的事件处理程序中,请MenuItem确保先调用set NotifyIcon.Visible = False,然后再调用Application.Exit()。将您需要的内容添加到ContextMenu并正确处理:)


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

当您到达Main的末尾并且没有UI线程时,程序将停止执行。您如何解决这是您的解决方案?如果您已经解决了这些问题,那么您将得到我的投票:)
马修·斯蒂普斯

你得到我的投票。也许只是提到您仍然需要在没有任何参数的情况下调用Application.Run?

更新了App.Run的替代方法。
Wolf5

我知道thread.sleep是过大的,但是如果您有一个比Application.Run更好的“ sleep”循环替代方法,请发布它:)
Wolf5

Thread.Sleep是个坏主意:与使用Application.Run相比,您最终将消耗更多的CPU和电池。
Sneftel

8

“系统任务栏”应用程序只是常规的win窗体应用程序,唯一的区别是它在Windows系统任务栏区域中创建了一个图标。为了创建sys.tray图标,请使用NotifyIcon组件,您可以在Toolbox(通用控件)中找到它,并修改其属性:Icon,工具提示。此外,它还使您能够处理鼠标单击和双击消息。

还有一件事情,是为了获得外观或标准的托盘应用程序。在您的主窗体显示事件上添加followinf行:

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

6

据我所知,您仍然必须使用表单编写应用程序,但是对表单没有控件,也永远不要将其设置为可见。使用NotifyIcon(可在此处找到MSDN示例)来编写您的应用程序。


1
不完全的。您的表单可以包含控件,但默认情况下应将其隐藏。
符文格里姆斯塔德2009年

5
您不需要任何形式。在创建新的Window App创建向导之后,只需删除Form1并删除打开它的代码即可。您可以使用带有NotifyIcon和ContextMenu的Program.cs编写所有内容。不再需要。
狼5

1
我知道它可以包含控件,但OP不希望它
马修尖塔

2

这是我使用Visual Studio 2010,.NET 4的方法

  1. 创建Windows窗体应用程序,在属性中设置“制作单实例应用程序”
  2. 添加一个ContextMenuStrip
  3. 将一些条目添加到上下文菜单栏中,双击它们以获取处理程序,例如,“退出”(双击)->处理程序-> me.Close()
  4. 添加一个NotifyIcon,在设计器中将contextMenuStrip设置为刚创建的一个,选择一个图标(您可以在VisualStudio文件夹中的“ common7 ...”下找到一些图标)
  5. 在设计器中设置表单的属性:FormBorderStyle:无,ShowIcon:false,ShowInTaskbar:false,不透明度:0%,WindowState:Minimized
  6. 在Form1_Load的末尾添加Me.Visible = false,这将在使用时隐藏图标 Ctrl +Tab
  7. 运行并根据需要进行调整。

2

对于Notification Area Application这是一个非常友好的框架...足以将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;
        }
    }
}

-2

只需添加

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

到您的表单对象。您将在系统托盘上仅看到一个图标。


这会将表格放在任务栏上方。不一样的东西。您是否要回复其他帖子?
LarsTech

1
任务栏上没有图标,我们看不到表格。可视程序仅存在于系统托盘中。以上 是什么意思?
YTerle 2015年

您的答案不包含任何上下文。您正在使用NotifyIcon类吗?如果没有,您的表单将最小化到任务栏上方的左下角。
LarsTech

1
如果您不忙,请尝试编写并运行它。
YTerle
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.