首页 > 编程语言 >程序异常退出后,托盘残留图标清理方法(C#)

程序异常退出后,托盘残留图标清理方法(C#)

时间:2024-04-08 15:58:03浏览次数:18  
标签:C# RefreshWindow WM 程序 托盘 var rect 图标

程序猿对于宕机再熟悉不过了,如果一个程序异常退出,那我们只能在Windows日志中找到它的踪迹;如果它是一个托盘程序,异常退出后,它会停留在托盘中久久不能离去,直到我们的鼠标从它身上划过;如果一个程序被另一个守护程序不断的杀掉、重启,那么它的结果会如下图所示,

  请注意!!这不是扫雷!!没错,这正是残留的图标。解决方法其实很简单,在程序每次开启前,向托盘窗口发送鼠标经过消息WM_MOUSEMOVE,使其刷新。

  首先要明确一点,托盘包括显示区域和溢出区域,所以需要同时刷新,防止遗漏。可以用Spy++鼠标右键选择“突出显示”,窗口轮廓就会闪烁,SysPager和NotifyIconOverflowWindow。

代码如下:

using System;
using System.Runtime.InteropServices;
  
public class TaskBarUtil
{
    struct RECT
    {
        public int left, top, right, bottom;
    }
  
    public static void RefreshNotification()
    {
        var NotifyAreaHandle = GetNotifyAreaHandle();
        if (NotifyAreaHandle != IntPtr.Zero)
            RefreshWindow(NotifyAreaHandle);
 
        var NotifyOverHandle = GetNotifyOverHandle();
        if (NotifyOverHandle != IntPtr.Zero)
            RefreshWindow(NotifyOverHandle);
    }
  
    private static void RefreshWindow(IntPtr windowHandle)
    {
        const uint WM_MOUSEMOVE = 0x0200;
        RECT rect;
        GetClientRect(windowHandle, out rect);
        for (var x = 0; x < rect.right; x += 5)
            for (var y = 0; y < rect.bottom; y += 5)
                SendMessage(windowHandle, WM_MOUSEMOVE, 0, (y << 16) + x);
    }
  
    private static IntPtr GetNotifyAreaHandle()
    {
        var TrayWndHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Shell_TrayWnd", string.Empty);
        var TrayNotifyWndHandle = FindWindowEx(TrayWndHandle, IntPtr.Zero, "TrayNotifyWnd", string.Empty);
        var SysPagerHandle = FindWindowEx(TrayNotifyWndHandle, IntPtr.Zero, "SysPager", string.Empty);
        var NotifyAreaHandle = FindWindowEx(SysPagerHandle, IntPtr.Zero, "ToolbarWindow32", string.Empty);
 
        return NotifyAreaHandle;
    }
   
    private static IntPtr GetNotifyOverHandle()
    {
        var OverHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "NotifyIconOverflowWindow", string.Empty);
        var NotifyOverHandle = FindWindowEx(OverHandle, IntPtr.Zero, "ToolbarWindow32", string.Empty);
         
        return NotifyOverHandle;
    }
  
    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
    [DllImport("user32.dll")]
    static extern bool GetClientRect(IntPtr handle, out RECT rect);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr handle, UInt32 message, Int32 wParam, Int32 lParam);
}

  

TaskBarUtil.RefreshNotification();

  托盘又恢复往日简洁 ^_^

标签:C#,RefreshWindow,WM,程序,托盘,var,rect,图标
From: https://www.cnblogs.com/chinasoft/p/18121351

相关文章

  • Memcache分布式布置方案--一致性Hash分布机制PHP实现
    一致性Hash分布简介在服务器数量不发生改变时,普通的Hash分布可以很好地运作。当服务器的数量发生改变时,问题就出来了,试想,增加一台服务器时,同一个key经过Hash之后,与服务器取模的结果跟没增加服务器之前的结果会不一样,这就导致之前保存的数据丢失。为了把丢失的数据减少到最少,可以采......
  • SpringBoot拦截器注入stringredistemplate出现Consider defining a bean of type 'org
    问题自定义拦截器需要注入StringRedisTemplate来通过token获取redis中的数据自定义拦截器代码@ComponentpublicclassLoginInterceptorimplementsHandlerInterceptor{@AutowiredprivateStringRedisTemplatestringRedisTemplate;@Overridepublicb......
  • Oracle 在谈 connect by level
     在开发的过程中遇到需要把一行数据显示成N行,当时马上就想到了connectbylevel 这个实在太好用了显示一行selectlevelrnfromdualconnectbylevel<2;显示二行selectlevelrnfromdualconnectbylevel<3; 实例:目前显示一行selectpha.segment1,......
  • Microbiome|北京林业大学生物多样性研究团队揭示土壤原核生物群落在推动亚热带森林植物
    生物多样性与生态系统功能(BEF)之间的关系是生态研究的重要课题之一。土壤微生物群落的变化可能是调节这种关系的关键因素之一。关于森林中真菌群落对树木多样性-生产力关系的影响,已有大量研究。然而,对于细菌和古细菌,尽管它们在森林土壤中数量众多,并具有重要的生态系统功能,但关......
  • Science Advances | 全球植物吸收的二氧化碳可能比我们想象的多20%
    在围绕气候变化及其对地球的深远影响的研究领域,几乎没有什么好消息可报告,然而一个国际科学家小组可能已经找到了一个值得庆祝的小胜利。西悉尼大学的于尔根-克瑙尔(JürgenKnauer)领导的科学家们利用现实的生态建模发现,全球植被实际吸收的人类排入大气中的二氧化碳可能会增加约2......
  • RuleEngine规则引擎底层改造AviatorScript 之函数执行
    https://gitee.com/aizuda/rule-engine-open需求:使用上述开源框架进行改造,底层更换成AviatorScript,函数实现改造。原本实现方式@OverridepublicObjectrun(ExecuteFunctionRequestexecuteTestRequest){IntegerfunctionId=executeTestRequest.ge......
  • 1169: 大整数(指针专题)(c语言)
    题目描述输入3个大整数,位数不超过100位,按从小到大的顺序输出这三个整数。要求定义并使用如下函数比较两个大整数的大小。 intcmp(char*a,char*b) { //若大整数a大于b,返回1; //若a小于b,返回-1; //若a与b相等,返回0 }输入输入有3行,每行输入一个大整数,位数不超过1......
  • 1022: 三整数排序(c语言)
    题目描述从键盘输入三个整数x,y和z,按从大到小的顺序输出它们的值。输入输入三个整数x,y和z。输出按从大到小的顺序输出它们的值。样例输入 201618样例输出 201816#include<stdio.h>intmain(){ intx=0,y=0,z=0; scanf("%d%d%d",&x,&y,&z);......
  • c语言分支结构
    正⽂开始C语⾔是结构化的程序设计语⾔,这⾥的结构指的是顺序结构、选择结构、循环结构,C语⾔是能够实现这三种结构的,其实我们如果仔细分析,我们⽇常所⻅的事情都可以拆分为这三种结构或者这三种结构的组合。我们可以使⽤if、switch实现分⽀结构,使⽤for、while、dowh......
  • echarts可拖拽折线图,拐点拖拽/点击定位/整体平移
    1.拐点拖拽,只有点击拐点才可以拖拽,并且限制了只能在当前X轴进行拖拽//chart myChart(){ constthat=this letsymbolSize=20; letdata=newArray(); letdataReal=newArray(); //this.real letlist=this.plan; letr......