csharp 清除被强制关闭进程的托盘图标
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 清除被强制关闭进程的托盘图标相关的知识,希望对你有一定的参考价值。
public static class WindowsExtend
{
#region NativeMethod
public const int MOUSEEVENTF_MOVE = 0x0001;
public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
public const int MOUSEEVENTF_RIGHTUP = 0x10;
public const int MOUSEEVENTF_LEFTDOWN = 0x02;
public const int MOUSEEVENTF_LEFTUP = 0x04;
const int WM_USER = 0x0400;
const int TB_BUTTONCOUNT = (WM_USER + 24);
const int TB_GETBUTTON = (WM_USER + 23);
const int TB_GETBUTTONTEXTW = (WM_USER + 45);
const int TB_DELETEBUTTON = (WM_USER + 22);
const int TB_HIDEBUTTON = (WM_USER + 4);
const int PROCESS_ALL_ACCESS = 0x1F0FFF;
const int PAGE_READWRITE = 0x4;
const int MEM_COMMIT = 0x1000;
const int MEM_RESERVE = 0x2000;
const int MEM_RELEASE = 0x8000;
[DllImport("user32.dll")]
public static extern bool SetCursorPos(int x, int y);
[DllImport("user32")]
public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr WindowFromPoint(int x, int y);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll")]
public extern static IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
[DllImport("User32.DLL")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("kernel32.dll")]
static extern int OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
static extern int VirtualAllocEx(int hwnd, int lpaddress, int size, int type, int tect);
[DllImport("kernel32.dll")]
static extern int VirtualFreeEx(int hwnd, int lpAddress, int dwSize, int dwFreeType);
[DllImport("kernel32.dll")]
static extern int ReadProcessMemory(int hProcess, int lpBaseAddress, out TBBUTTON64 aTBInfo, int nSize, int lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
static extern int ReadProcessMemory(int hProcess, int lpBaseAddress, out TBBUTTON32 aTBInfo, int nSize, int lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
static extern int ReadProcessMemory(int hProcess, int lpBaseAddress, out TRAYDATA aTrayData, int nSize, int lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
static extern int ReadProcessMemory(int hProcess, int lpBaseAddress, StringBuilder aBuffer, int nSize, int lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
static extern int CloseHandle(int hObject);
struct TBBUTTON32
{
int iBitmap;
public int idCommand;
byte fsState;
byte fsStyle;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)]
byte[] bReserved;
public IntPtr dwData;
IntPtr iString;
}
struct TBBUTTON64
{
int iBitmap;
public int idCommand;
byte fsState;
byte fsStyle;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6)]
byte[] bReserved;
public IntPtr dwData;
IntPtr iString;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TRAYDATA
{
public IntPtr hwnd;
public int uID;
public int uCallbackMessage;
public int bReserved0;
public int bReserved1;
public IntPtr hIcon;
}
struct NOTIFYICONDATA
{
public int Size;
public IntPtr HWnd;
public int ID;
public int Flags;
public int CallbackMessage;
public IntPtr HIcon;
}
[DllImport("shell32.dll")]
static extern bool Shell_NotifyIcon(uint dwMessage, ref NOTIFYICONDATA pnid);
#endregion
#region ClearTrayIcon
public static bool ClearKilledTrayIcon()
{
bool aResult = false;
foreach (NOTIFYICONDATA aTrayData in SearchKilledTrayIcons())
{
NOTIFYICONDATA aData = aTrayData;
aResult = true;
Shell_NotifyIcon(2, ref aData);
}
return aResult;
}
private static List<NOTIFYICONDATA> SearchKilledTrayIcons()
{
List<NOTIFYICONDATA> aRestult = new List<NOTIFYICONDATA>();
//Tray overflow panel
IntPtr aNotifyIconOverflowWindowHwnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "NotifyIconOverflowWindow", null);
IntPtr aToolbarWindow32Hwnd = FindWindowEx(aNotifyIconOverflowWindowHwnd, IntPtr.Zero, "ToolbarWindow32", null);
SearchInternelKilledTrayIcons(ref aRestult, aToolbarWindow32Hwnd);
//Tray Tool bar
IntPtr aWindowHwnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Shell_TrayWnd", null);
aWindowHwnd = FindWindowEx(aWindowHwnd, IntPtr.Zero, "TrayNotifyWnd", null);
aWindowHwnd = FindWindowEx(aWindowHwnd, IntPtr.Zero, "SysPager", null);
aWindowHwnd = FindWindowEx(aWindowHwnd, IntPtr.Zero, "ToolbarWindow32", null);
SearchInternelKilledTrayIcons(ref aRestult, aWindowHwnd);
return aRestult;
}
private static void SearchInternelKilledTrayIcons(ref List<NOTIFYICONDATA> aRestult, IntPtr aToolbarWindow32Hwnd)
{
int aProcessID;
GetWindowThreadProcessId(aToolbarWindow32Hwnd, out aProcessID);
int hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, aProcessID);
if (hProcess > 0)
{
int aBufferPtr = 0;
int aTitleBufferPtr = 0;
aBufferPtr = VirtualAllocEx(hProcess, 0, 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
aTitleBufferPtr = VirtualAllocEx(hProcess, 0, 256, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
int btnCount = SendMessage(aToolbarWindow32Hwnd, TB_BUTTONCOUNT, 0, 0);
for (int i = 0; i < btnCount; i++)
{
int aIsOK = SendMessage(aToolbarWindow32Hwnd, TB_GETBUTTON, i, aBufferPtr);
if (aIsOK != 0)
{
aIsOK = 0;
int aTBButtonCommand = 0;
IntPtr aParentHwndPtr;
#region Read TBBUTTON
if (Environment.Is64BitOperatingSystem)
{
TBBUTTON64 aTBInfo = new TBBUTTON64();
aIsOK = ReadProcessMemory(hProcess, aBufferPtr, out aTBInfo, Marshal.SizeOf(aTBInfo), 0);
aTBButtonCommand = aTBInfo.idCommand;
aParentHwndPtr = aTBInfo.dwData;
}
else
{
TBBUTTON32 aTBInfo = new TBBUTTON32();
aIsOK = ReadProcessMemory(hProcess, aBufferPtr, out aTBInfo, Marshal.SizeOf(aTBInfo), 0);
aTBButtonCommand = aTBInfo.idCommand;
aParentHwndPtr = aTBInfo.dwData;
}
#endregion
if (aIsOK != 0)
{
//Tray Icon Title
//SendMessage(aToolbarWindow32Hwnd, TB_GETBUTTONTEXTW, aTBButtonCommand, aTitleBufferPtr);
//StringBuilder buffer = new StringBuilder(256);
//buffer.Clear();
//ReadProcessMemory(hProcess, aTitleBufferPtr, buffer, buffer.Capacity, 0);
aIsOK = 0;
TRAYDATA trayData = new TRAYDATA();
aIsOK = ReadProcessMemory(hProcess, aParentHwndPtr.ToInt32(), out trayData, Marshal.SizeOf(trayData), 0);
if (aIsOK != 0)
{
int dwProcessId = 0;
GetWindowThreadProcessId(trayData.hwnd, out dwProcessId);
if (dwProcessId == 0)
{
NOTIFYICONDATA pnid = new NOTIFYICONDATA();
pnid.Flags = 1 | 2 | 4;
pnid.HWnd = trayData.hwnd;
pnid.HIcon = trayData.hIcon;
pnid.ID = trayData.uID;
pnid.Size = Marshal.SizeOf(pnid);
aRestult.Add(pnid);
}
}
}
}
}
VirtualFreeEx(hProcess, aTitleBufferPtr, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, aBufferPtr, 0, MEM_RELEASE);
CloseHandle(hProcess);
}
}
#endregion
}
以上是关于csharp 清除被强制关闭进程的托盘图标的主要内容,如果未能解决你的问题,请参考以下文章
WinForm 关于任务栏图标进程结束后图标无法自动清除的问题!
csharp SingleInstance Windows窗体 - 托盘栏中的通知图标