C# 通知图标不显示
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/842494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NotifyIcon not showing
提问by Tester101
I am writing a simple application that I would like to control with a notifyIcon rather than a form, I have follwed examples I found through Google, but my notifyIcon will not show up. What am I doing wrong?
我正在编写一个简单的应用程序,我想用notifyIcon 而不是表单来控制它,我遵循了通过Google 找到的示例,但我的notifyIcon 不会显示。我究竟做错了什么?
static class MainEntryClass
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
C2F TestApp = new C2F();
Application.Run();
TestApp.Dispose();
}
}
class C2F
{
public C2F()
{
InitializeComponent();
loadSettings();
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(C2F));
this.niC2F = new System.Windows.Forms.NotifyIcon(this.components);
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.separatorToolStripMenuItem = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuStrip1.SuspendLayout();
//
// niC2F
//
this.niC2F.BalloonTipText = "MyApp";
this.niC2F.Icon = ((System.Drawing.Icon)(Clipboard2File.Properties.Resources.ResourceManager.GetObject("MyIcon.ico")));
this.niC2F.Text = "MyApp";
this.niC2F.ContextMenuStrip = this.contextMenuStrip1;
this.niC2F.ShowBalloonTip(5);
this.niC2F.Visible = true;
this.niC2F.MouseClick += new System.Windows.Forms.MouseEventHandler(this.niC2F_MouseClick);
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.settingsToolStripMenuItem,
this.separatorToolStripMenuItem,
this.exitToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(153, 76);
//
// settingsToolStripMenuItem
//
this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
this.settingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.settingsToolStripMenuItem.Text = "Settings";
this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click);
//
// separatorToolStripMenuItem
//
this.separatorToolStripMenuItem.Name = "separatorToolStripMenuItem";
this.separatorToolStripMenuItem.Size = new System.Drawing.Size(149, 6);
this.separatorToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// exitToolStripMenuItem1
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem1";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.exitToolStripMenuItem.Text = "Exit";
}
private System.ComponentModel.IContainer components = null;
private Form1 frmSettings = new Form1();
private Settings C2FSettings = new Settings();
private System.Windows.Forms.NotifyIcon niC2F;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator separatorToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
}
采纳答案by Jared Harley
I actually just finished a project that started as a NotifyIcon. Your code (I'm guessing you just provided a snippet) is incredibly similar to mine.
我实际上刚刚完成了一个作为 NotifyIcon 开始的项目。您的代码(我猜您只是提供了一个片段)与我的非常相似。
I checked your code, and the only change I had to make to get it to work was changing the way you called the icon to:
我检查了你的代码,我必须做的唯一改变是改变你调用图标的方式:
this.niC2F.Icon = new System.Drawing.Icon(@"C:\PathToIcon\iconfile.ico");
Below is a working sample with a right-click menu and double-click functionality:
下面是一个带有右键单击菜单和双击功能的工作示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace TestApp
{
static class MainEntryClass
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
C2F TestApp = new C2F();
Application.Run();
}
}
class C2F
{
System.ComponentModel.Container component;
System.Drawing.Icon icon;
ContextMenuStrip rightClickMenu = new ContextMenuStrip();
NotifyIcon trayIcon;
ToolStripMenuItem options = new ToolStripMenuItem();
ToolStripMenuItem restore = new ToolStripMenuItem();
ToolStripMenuItem exit = new ToolStripMenuItem();
ToolStripSeparator seperator = new ToolStripSeparator();
public C2F()
{
InitializeComponent();
}
private void InitializeComponent()
{
icon = new System.Drawing.Icon(@"C:\PathToIcon\iconfile.ico");
component = new System.ComponentModel.Container();
trayIcon = new NotifyIcon(component);
trayIcon.Text = "Bill Reminder";
trayIcon.Icon = icon;
trayIcon.Visible = true;
trayIcon.DoubleClick += new EventHandler(trayIcon_DoubleClick);
trayIcon.ContextMenuStrip = rightClickMenu;
rightClickMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
{
options,
seperator,
restore,
exit
});
options.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
options.Text = "Options";
options.Click += new EventHandler(options_Click);
restore.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
restore.Text = "Restore Window";
restore.Click += new EventHandler(restore_Click);
exit.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
exit.Text = "Exit";
exit.Click += new EventHandler(exit_Click);
}
void exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
void restore_Click(object sender, EventArgs e)
{
FormName showWindow = new FormName();
showWindow.Show();
}
void options_Click(object sender, EventArgs e)
{
Settings_Window settings = new Settings_Window();
settings.Show();
}
void trayIcon_DoubleClick(object sender, EventArgs e)
{
FormName showWindow = new FormName();
showWindow.Show();
}
}
}
Hope this helps you, let me know if you have any questions!
希望能帮到你,有什么问题可以私信我!
回答by mistika
One more reason why NotifyIcon is not shown is if Windows Explorer is running with elevated privileges while your tray application isn't (only on systems with UAC of course).
未显示 NotifyIcon 的另一个原因是,如果 Windows 资源管理器以提升的权限运行,而您的托盘应用程序则没有(当然仅在具有 UAC 的系统上)。
This can happen if explorer.exe crashed or was killed, and then user manually restarted it from the elevated Task Manager.
如果 explorer.exe 崩溃或被杀死,然后用户从提升的任务管理器手动重新启动它,就会发生这种情况。
NotifyIcon control uses Shell_NotifyIcon native method inside, but doesn't check for the return value. If Shell_NotifyIcon returns FALSE, you won't be ever notified.
NotifyIcon 控件在内部使用 Shell_NotifyIcon 本地方法,但不检查返回值。如果 Shell_NotifyIcon 返回 FALSE,您将永远不会收到通知。
I had to breakpoint with WinDbg on Shell_NotifyIcon and GetLastError gave me ERROR_ACCESS_DENIED. So I realized that there's a permission issue, and it might be caused by restarted explorer elevation. Further tests confirmed this assumption.
我不得不在 Shell_NotifyIcon 上用 WinDbg 断点,GetLastError 给了我 ERROR_ACCESS_DENIED。所以我意识到存在权限问题,它可能是由重新启动的资源管理器提升引起的。进一步的测试证实了这一假设。
However this is rather rare case.
不过这种情况比较少见。