【发布时间】:2012-01-10 16:08:59
【问题描述】:
我有一个带有系统托盘图标的应用程序。卸载时,如果该进程正在运行,我将终止该进程。因此,由于没有优雅地停止应用程序,该图标仍保留在系统托盘中,并且只有当我们将鼠标悬停在其上时才会移除。我编写了一个代码,它将沿着托盘运行光标并将光标返回到其初始位置。这就是我所做的:
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string className, string windowName);
[DllImport("user32.dll")]
static extern IntPtr FindWindowEx(IntPtr parent, IntPtr child, string className, string windowName);
[DllImport("user32.dll")]
static extern bool GetWindowRect(HandleRef handle, out RECT rct);
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
void RefreshTray()
{
IntPtr taskbar_Handle = FindWindow("Shell_Traywnd", "");
IntPtr tray_Handle = FindWindowEx(taskbar_Handle, IntPtr.Zero, "TrayNotifyWnd", "");
RECT rct;
if (!(GetWindowRect(new HandleRef(null, tray_Handle), out rct)))
{
}
System.Drawing.Point init = Control.MousePosition;
for (int i = rct.Left; i < rct.Right-20; i++)
{
Cursor.Position = new System.Drawing.Point(i, (rct.Bottom + rct.Top) / 2);
}
Cursor.Position = init;
}
这在所有情况下都很好,除非启用了“不显示通知图标”选项。在这种情况下,有什么方法可以刷新托盘吗?
编辑 正如 cmets 建议的那样,我改变了方法。我没有杀死托盘应用程序,而是在我的应用程序服务(是的,忘了提,我也有一个与应用程序一起运行的服务)和托盘应用程序之间建立了通信。在卸载时,我会停止服务,从服务停止方法中,我会向托盘应用程序发送一个特定格式的套接字消息并要求它关闭,我会将通知图标可见性设置为 false。这将使托盘应用程序在后台运行,因此我使用“taskkill”来删除该应用程序。它在 Win7 和 Vista 中运行良好,但在 Win XP 中无法正常运行。但是我还没有编写任何特定于环境的代码。有什么可能的线索吗?
【问题讨论】:
-
我曾经遇到过类似的情况。我所做的是在 Form_Closing 事件中从 NotifyIcon 组件中处理出来,并且效果很好。
-
一种不那么老套的方法可能是通过卸载程序与您的应用程序进行通信。 (虽然我没有这方面的知识)
-
你不想写这样的代码。不要杀人,好好问。
-
不要终止进程。要求关闭。写上面的代码绝对没有任何意义。
-
谢谢大家!会关闭应用程序。
标签: c# pinvoke system-tray trayicon