[Solved] How to detect apps running in the system tray?
[Solved] How to detect apps running in the system tray?
I need to know if an app is running when the only indication of it is its icon in the system tray (ie. no other open window on the desktop). Before you ask, I won't know its exe name so can't look for that as a running process. The end goal is to obtain a list of all open apps, and I can of course easily find all opened and minimized app windows, but not system-trayed ones. So, how would you go about this? Thanks.
Last edited by BarryG on Wed Mar 01, 2023 3:09 am, edited 1 time in total.
Re: How to detect apps running in the system tray?
Find window Shell_TrayWnd, get ToolbarWindow32, count number of icons with TB_BUTTONCOUNT, get button text.
Look for the TB_BUTTONCOUNT constant in the "winapi_library" archive code, there are 3 examples there.
So that you do not suffer from searches, I took an example from there:
searched for the Find_PB_TrayIcons function, found another link, link
Look for the TB_BUTTONCOUNT constant in the "winapi_library" archive code, there are 3 examples there.
So that you do not suffer from searches, I took an example from there:
Code: Select all
; Author: NM, RASHAD
EnableExplicit
Define EventID
Define x
Global count,turn,hWnd,HDN,Name$
Global Dim Stray$(50),Dim Icon(50),Dim HDname$(12)
Structure TRAYDATA
hwnd.i
uID.l
uCallbackMessage.l
Reserved.l[2]
hIcon.i
EndStructure
Structure TRAYDATA_wow64
hwnd.q
uID.l
uCallbackMessage.l
Reserved.l[2]
hIcon.i
EndStructure
Structure TBBUTTON_wow64
iBitmap.l
idCommand.l
fsState.b
fsStyle.b
bReserved.b[6]
dwData.q
iString.q
EndStructure
Procedure Is64Bit()
Protected bIsWow64.l = #False, fnIsWow64Process
fnIsWow64Process = GetProcAddress_(GetModuleHandle_("kernel32"), "IsWow64Process")
If fnIsWow64Process
If Not CallFunctionFast(fnIsWow64Process, GetCurrentProcess_(), @bIsWow64)
EndIf
EndIf
ProcedureReturn bIsWow64
EndProcedure
Procedure.s GetImageName(PID)
Protected IName$
Protected *dfn
Protected hProc
OpenLibrary(0, "psapi.dll")
IName$ = Space(#MAX_PATH)
CompilerIf #PB_Compiler_Unicode
*dfn = GetFunction(0, "GetProcessImageFileNameW")
CompilerElse
*dfn = GetFunction(0, "GetProcessImageFileNameA")
CompilerEndIf
hProc = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, PID)
CallFunctionFast(*dfn, hProc, @IName$, #MAX_PATH)
ProcedureReturn IName$
EndProcedure
Procedure Find_PB_TrayIcons()
Protected n
Protected hwnd
Protected hTray
Protected dwExplorerThreadId
Protected dwExplorerProcessId
Protected hProc
Protected *lpData
Protected *lpRect
Protected i
Protected hIcon
Protected uID
Protected iState
Protected IName$
Protected x
Protected Position
If Is64Bit()
Dim button_td2.TRAYDATA_wow64(20)
Dim button2.TBBUTTON_wow64 (20)
Else
Dim button_td.TRAYDATA(20)
Dim button.TBBUTTON (20)
EndIf
For n = 1 To 2
If n = 1
hWnd = FindWindow_("Shell_TrayWnd", #Null)
If hWnd
hWnd = FindWindowEx_(hWnd, #Null, "TrayNotifyWnd", #Null)
If hWnd
hWnd = FindWindowEx_(hWnd,#Null, "SysPager", #Null)
If hWnd
hTray = FindWindowEx_(hWnd, #Null, "ToolbarWindow32", #Null)
Else
ProcedureReturn 0
EndIf
Else
ProcedureReturn 0
EndIf
Else
ProcedureReturn 0
EndIf
count = SendMessage_(hTray, #TB_BUTTONCOUNT, 0, 0)
ElseIf n = 2
hWnd = FindWindow_("NotifyIconOverflowWindow", #Null)
If hWnd
hTray = FindWindowEx_(hWnd, #Null, "ToolbarWindow32", #Null)
Else
ProcedureReturn 0
EndIf
count = count + SendMessage_(hTray, #TB_BUTTONCOUNT, 0, 0)
EndIf
dwExplorerThreadId=GetWindowThreadProcessId_(hTray, @dwExplorerProcessId)
hProc = OpenProcess_(#PROCESS_ALL_ACCESS, #False, dwExplorerProcessId)
If Is64Bit()
*lpData = VirtualAllocEx_(hProc, #Null, SizeOf(TBBUTTON_wow64)*count, #MEM_COMMIT, #PAGE_READWRITE)
Else
*lpData = VirtualAllocEx_(hProc, #Null, SizeOf(TBBUTTON)*count, #MEM_COMMIT, #PAGE_READWRITE)
EndIf
*lpRect = VirtualAllocEx_(hProc, #Null, SizeOf(RECT)*count, #MEM_COMMIT, #PAGE_READWRITE)
For i = 0 To count - 1
If Is64Bit()
SendMessage_(hTray, #TB_GETBUTTON, i, *lpData+i*SizeOf(TBBUTTON_wow64) )
ReadProcessMemory_(hProc, *lpData+(i*SizeOf(TBBUTTON_wow64)), @button2.TBBUTTON_wow64(i), SizeOf(TBBUTTON_wow64), #Null)
ReadProcessMemory_(hProc, button2(i)\dwData, @button_td2.TRAYDATA_wow64(i), SizeOf(TRAYDATA_wow64), #Null)
hIcon = button_td2.TRAYDATA_wow64(i)\hIcon
hWnd = button_td2.TRAYDATA_wow64(i)\hwnd
uID = button_td2.TRAYDATA_wow64(i)\uID
iState = button2.TBBUTTON_wow64(i)\fsState
IName$ = GetImageName(uID)
If Trim(IName$) = ""
IName$ = "System Icon"
Else
For x = 1 To 3
Position = FindString(IName$,"\",Position+1)
Next
IName$ = Right(IName$,Len(IName$)-Position)
For x = 0 To HDN
IName$ = HDname$(x)+IName$
If FileSize(IName$) > 0
Break
EndIf
Next
EndIf
If n = 1
turn = i
STray$(turn) = " " + Str(hIcon) + Chr(10) + Str(hWnd) + Chr(10) + Str(iState) + Chr(10) + Str(uID) + Chr(10) + IName$
Else
turn = turn + 1
STray$(turn) = " " + Str(hIcon) + Chr(10) + Str(hWnd) + Chr(10) + "OFN" + Chr(10) + Str(uID) + Chr(10) + IName$
EndIf
Icon(turn) = hIcon
Else
SendMessage_(hTray, #TB_GETBUTTON, i, *lpData+i*SizeOf(TBBUTTON) )
ReadProcessMemory_(hProc, *lpData+(i*SizeOf(TBBUTTON)), @button.TBBUTTON(i), SizeOf(TBBUTTON), #Null)
ReadProcessMemory_(hProc, button(i)\dwData, @button_td.TRAYDATA(i), SizeOf(TRAYDATA), #Null)
hIcon = button_td.TRAYDATA(i)\hIcon
hWnd = button_td.TRAYDATA(i)\hwnd
uID = button_td.TRAYDATA(i)\uID
iState = button.TBBUTTON(i)\fsState
IName$ = GetImageName(uID)
If Trim(IName$) = ""
IName$ = "System Icon"
Else
For x = 1 To 3
Position = FindString(IName$,"\",Position+1)
Next
IName$ = Right(IName$,Len(IName$)-Position)
For x = 0 To HDN
IName$ = HDname$(x)+IName$
If FileSize(IName$) > 0
Break
EndIf
Next
EndIf
If n = 1
turn = i
STray$(turn) = " " + Str(hIcon) + Chr(10) + Str(hWnd) + Chr(10) + Str(iState) + Chr(10) + Str(uID) + Chr(10) + IName$
Else
turn = turn + 1
STray$(turn) = " " + Str(hIcon) + Chr(10) + Str(hWnd) + Chr(10) + "OFN" + Chr(10) + Str(uID) + Chr(10) + IName$
EndIf
Icon(turn) = hIcon
EndIf
Next
Next
VirtualFreeEx_(hProc, *lpData, #Null, #MEM_RELEASE)
VirtualFreeEx_(hProc, *lpRect, #Null, #MEM_RELEASE)
CloseHandle_(hProc)
EndProcedure
If OpenWindow(0, 0, 0, 500, 400, "Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0,10,10,780,580,"Icon-Icon Handle", 100, #PB_ListIcon_GridLines)
SetGadgetColor(0, #PB_Gadget_FrontColor, $FD4B0B)
SetGadgetColor(0, #PB_Gadget_BackColor, $E8FEFE)
AddGadgetColumn(0, 1, "Win Handle", 80)
AddGadgetColumn(0, 2, "Status", 45)
AddGadgetColumn(0, 3, "PID", 50)
AddGadgetColumn(0, 4, "Image name", 500)
Find_PB_TrayIcons()
For x = 0 To count-1
AddGadgetItem(0,-1, STray$(x), Icon(x))
Next
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_CloseWindow
End
EndIf
ForEver
EndIf
Re: How to detect apps running in the system tray?
Thanks for the links, AZJIO!
This is the one that does what I need -> viewtopic.php?t=51549
It shows the exe name of each system tray icon, which is what I'm after. Much appreciated!
This is the one that does what I need -> viewtopic.php?t=51549
It shows the exe name of each system tray icon, which is what I'm after. Much appreciated!
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: [Solved] How to detect apps running in the system tray?
I've been compressed! I only hope it was lossless...; Author: NM, RASHAD
BERESHEIT