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

Posted

技术标签:

【中文标题】如何制作仅在系统托盘中运行的 .NET Windows 窗体应用程序?【英文标题】:How can I make a .NET Windows Forms application that only runs in the System Tray? 【发布时间】:2010-11-02 23:18:22 【问题描述】:

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

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

一个图标 工具提示和 “右键单击”菜单。

【问题讨论】:

codeproject.com/Articles/18683/Creating-a-Tasktray-Application 大多数答案都缺少一些东西 - 不要忘记在退出应用程序时设置icon.Visible = false,然后设置Dispose() 图标。否则,程序退出后您仍会看到该图标。经过几次测试,您将不再知道哪个图标是真实的。 如果你追求更现代的 WPF 方法 - 你可以试试这个:codeproject.com/Articles/36788/… 仅作记录,这里有一个关于托盘应用程序的非常综合文章的链接(来自已删除的答案):simple-talk.com/dotnet/.net-framework/… 【参考方案1】:

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

基本上将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();
    

【讨论】:

这是一个很好的起点。注意“AppIcon”必须是你用“Project -> Properties -> Resources -> Add Resource”添加的资源的名称,然后重新编译项目。 我做了 properties..resources..add resource..icon.. 重新编译,仍然得到“错误 CS0103 The name 'Resources' does not exist in the current context” @barlop 我不得不这样写:Properites.Resources.AppIcon @SimonPerepelitsa 谢谢,我不确定我在实验中做了什么,我的意思是评论什么有效,但我一定忘记了我所做的一些有效的事情。但最终我使用的方法是从你可以拖动的东西的调色板中拖动一个通知图标。然后在表单上点击它,点击一个小箭头,它会弹出一个菜单来为它选择一个图标!【参考方案2】:

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:
    使用向导创建一个新的 Windows 应用程序。 从代码中删除Form1。 删除 Program.cs 中启动 Form1 的代码。 使用NotifyIcon 类创建您的系统托盘图标(为其分配一个图标)。 为其添加上下文菜单。 或对NotifyIcon 的鼠标单击做出反应并区分右键单击和左键单击,设置上下文菜单并显示按下哪个按钮(右/左)。 Application.Run() 保持应用程序运行,Application.Exit() 退出。或bool bRunning = true; while(bRunning)Application.DoEvents(); Thread.Sleep(10);。然后设置bRunning = false;退出应用。

【讨论】:

程序在到达 Main 的末尾并且没有 UI 线程时停止执行。你如何照顾这是你的解决方案?如果您解决了这些问题,那么您将获得我的投票 :) 你得到我的投票。也许只是提到您仍然需要在没有任何参数的情况下调用 Application.Run? 更新为 App.Run 的替代品。 我知道 thread.sleep 太过分了,但如果你有一个更好的“睡眠”循环替代 Application.Run 做发布它:) Thread.Sleep 是个坏主意:你最终会使用更多的 CPU 和电池,而不是像你想要的那样执行 Application.Run。【参考方案5】:

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

还有一件事,以实现外观或标准托盘应用程序。在主窗体显示事件中添加以下行:

private void MainForm_Shown(object sender, EventArgs e)

    WindowState = FormWindowState.Minimized;
    Hide();
 

【讨论】:

【参考方案6】:

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

【讨论】:

不完全。您的表单可以包含控件,但默认情况下应该隐藏。 您不需要任何表格。在一个新的 Window App 创建向导之后,只需删除 Form1 并删除打开它的代码。您可以在 Program.cs 中使用 NotifyIcon 和 ContextMenu 编写所有内容。没有其他要求了。 我知道它可以包含控件,但 OP 不想要它【参考方案7】:

以下是我使用 Visual Studio 2010、.NET 4 的方法

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

【讨论】:

【参考方案8】:

它是一个非常友好的通知区域应用程序框架......将 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;
        
    

【讨论】:

【参考方案9】:
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);

【讨论】:

您好,欢迎来到 Stack Overflow!请拨打tour。感谢您提供答案,但您能否添加关于您的代码如何解决问题的说明?【参考方案10】:

您可以创建表单,对其进行修改,然后将其作为参数传递给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 并且有关联的图标。这还可以让您使用以后出于任何原因可能需要的表单

【讨论】:

【参考方案11】:

简单添加

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

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

【讨论】:

这会将表单置于任务栏之上。不是一回事。您是否要回复其他帖子? 任务栏上没有图标,我们看不到表单。视觉程序仅存在于系统托盘中。 以上是什么意思? 您的回答不包含任何上下文。你在使用 NotifyIcon 类吗?如果没有,您的表单将最小化到任务栏上方的左下角。 如果您不忙,请尝试编写并运行它。 this.ShowInTaskbar = false 导致表单不显示在任务栏中(即使在最小化时),this.WindowState = FormWindowState.Minimized 导致表单开始在屏幕上不可见。所以表格不会出现在任何地方。无法集中注意力或恢复它,应用程序在后台愉快地运行。如果您将托盘图标添加到您的应用程序,那么您的应用程序将仅显示为托盘图标,没有其他任何内容。您可以将 ContextMenuStrip 添加到通知图标以允许交互(和关闭应用程序)。

以上是关于如何制作仅在系统托盘中运行的 .NET Windows 窗体应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 VB.NET 中制作自己的组件?

如何仅在当前运行的 Windows 会话上制作 Grapevine REST 服务器

如何使用系统托盘/任务栏图标制作跨平台 Kivy 应用程序,即使应用程序没有聚焦/处于任务栏模式,它也会检测键盘输入

如何把程序最小化到托盘图标

JavaFX:系统托盘

开发一个简单的Windows系统托盘桌面应用程序来使用.NET Web服务