Как получить информацию о системном трее в Python?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как получить информацию о системном трее в Python?

Сообщение Anonymous »

Как пройтись по панели задач и получить в нем информацию о значке?
Например, значок, процесс, который его создал...
Я нашел страницу, на которой соответствует моим требованиям, я переписал его код на Python, правильно используя ctypes.
Исходный код основан на Windows 10.

Код: Выделить всё

import ctypes
from ctypes import wintypes

# 定义常量
PROCESS_VM_OPERATION = 0x0008
PROCESS_VM_READ = 0x0010
PROCESS_VM_WRITE = 0x0020
MEM_COMMIT = 0x00001000
PAGE_EXECUTE_READWRITE = 0x40
MEM_RELEASE = 0x00008000
TB_BUTTONCOUNT = 0x0400 + 24
TB_GETBUTTON = 0x0417

# 定义结构体
class SYSTEM_INFO(ctypes.Structure):
_fields_ = [
('wProcessorArchitecture', wintypes.WORD),
('wReserved', wintypes.WORD),
('dwPageSize', wintypes.DWORD),
('lpMinimumApplicationAddress', wintypes.LPVOID),
('lpMaximumApplicationAddress', wintypes.LPVOID),
('dwActiveProcessorMask', wintypes.DWORD),
('dwNumberOfProcessors', wintypes.DWORD),
('dwProcessorType', wintypes.DWORD),
('dwAllocationGranularity', wintypes.DWORD),
('wProcessorLevel', wintypes.WORD),
('wProcessorRevision', wintypes.WORD)
]

class TBBUTTON(ctypes.Structure):
_fields_ = [
('iBitmap', ctypes.c_int),
('idCommand', ctypes.c_int),
('fsState', ctypes.c_byte),
('fsStyle', ctypes.c_byte),
('bReserved', ctypes.c_byte * 6),
('dwData', ctypes.c_void_p),
('iString', ctypes.c_void_p)
]

# 定义函数
def Is64bitSystem():
si = SYSTEM_INFO()
ctypes.windll.kernel32.GetNativeSystemInfo(ctypes.byref(si))
return si.wProcessorArchitecture in [ctypes.wintypes.WORD(9), ctypes.wintypes.WORD(6)]

def FindTrayWnd():
hWnd = ctypes.windll.user32.FindWindowW("Shell_TrayWnd", None)
hWnd = ctypes.windll.user32.FindWindowExW(hWnd, None, "TrayNotifyWnd", None)
hWnd = ctypes.windll.user32.FindWindowExW(hWnd, None, "SysPager", None)
hWnd = ctypes.windll.user32.FindWindowExW(hWnd, None, "ToolbarWindow32", None)
return hWnd

def FindNotifyIconOverflowWindow():
hWnd = ctypes.windll.user32.FindWindowW("NotifyIconOverflowWindow", None)
hWnd = ctypes.windll.user32.FindWindowExW(hWnd, None, "ToolbarWindow32", None)
return hWnd

def EnumNotifyWindow(hWnd):
# 获取托盘进程ID
dwProcessId = wintypes.DWORD()
ctypes.windll.user32.GetWindowThreadProcessId(hWnd, ctypes.byref(dwProcessId))
if dwProcessId.value == 0:
print("GetWindowThreadProcessId failed:", ctypes.windll.kernel32.GetLastError())
return False

# 获取托盘进程句柄
hProcess = ctypes.windll.kernel32.OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, False, dwProcessId)
if hProcess == 0:
print("OpenProcess failed:", ctypes.windll.kernel32.GetLastError())
return False

# 在进程虚拟空间中分配内存,用来接收 TBBUTTON 结构体指针
p_tbbutton = ctypes.windll.kernel32.VirtualAllocEx(hProcess, 0, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
if p_tbbutton == 0:
print("VirtualAllocEx failed:", ctypes.windll.kernel32.GetLastError())
return False

# 初始化
dw_addr_dwData = 0
buff = ctypes.create_string_buffer(1024)
h_mainWnd = None
i_data_offset = 12
i_str_offset = 18

# 判断 x64
if Is64bitSystem():
i_data_offset += 4
i_str_offset += 6

# 获取托盘图标个数
i_buttons = ctypes.windll.user32.SendMessageW(hWnd, TB_BUTTONCOUNT, 0, 0)
if i_buttons != 0:
print("TB_BUTTONCOUNT message failed:", ctypes.windll.kernel32.GetLastError())
return False
i_buttons = 2

# 遍历托盘
for i in range(i_buttons):
# 获取 TBBUTTON 结构体指针
if not ctypes.windll.user32.SendMessageW(hWnd, TB_GETBUTTON, i, p_tbbutton):
print("TB_GETBUTTON message failed:", ctypes.windll.kernel32.GetLastError())
return False

# 读 TBBUTTON.dwData(附加信息)
ctypes.windll.kernel32.ReadProcessMemory(hProcess, ctypes.c_void_p(p_tbbutton.value + i_data_offset), ctypes.byref(dw_addr_dwData), 4, None)
if dw_addr_dwData:
ctypes.windll.kernel32.ReadProcessMemory(hProcess, ctypes.c_void_p(dw_addr_dwData), buff, 1024, None)
h_mainWnd = ctypes.cast(buff.raw[:4],  ctypes.POINTER(wintypes.HWND)).contents
ws_filePath = ctypes.c_wchar_p(buff.raw[i_str_offset:i_str_offset + ctypes.sizeof(wintypes.WCHAR) * ctypes.sizeof(wintypes.MAX_PATH)])
ws_tile = ctypes.c_wchar_p(buff.raw[i_str_offset + ctypes.sizeof(wintypes.WCHAR) * ctypes.sizeof(wintypes.MAX_PATH):])
print("hMainWnd =", hex(h_mainWnd.value))
print("strFilePath =", ws_filePath.value)
print("strTile =", ws_tile.value)

# 清理
dw_addr_dwData = 0
h_mainWnd = None

print()

ctypes.windll.kernel32.VirtualFreeEx(hProcess, p_tbbutton, 0, MEM_RELEASE)
ctypes.windll.kernel32.CloseHandle(hProcess)

return True

def main():
# 解决控制台中文 '?'
import locale
locale.setlocale(locale.LC_ALL, "chs")

# 获取托盘句柄
h_tray = FindTrayWnd()
h_tray_fold = FindNotifyIconOverflowWindow()

# 遍历托盘窗口
if not EnumNotifyWindow(h_tray) or not EnumNotifyWindow(h_tray_fold):
print("EnumNotifyWindow false.")

input()

if __name__ == "__main__":
main()

Однако это не работает в Windows 11...
В строке 92 кода я обнаружил, что переменная «i_buttons» всегда равна 0.
/>Я не хочу использовать ЛЮБУЮ большую библиотеку (например, PyQt) для решения своей проблемы, спасибо.

Подробнее здесь: https://stackoverflow.com/questions/792 ... -in-python
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как скрыть JFrame в системном трее панели задач
    Гость » » в форуме JAVA
    0 Ответы
    18 Просмотры
    Последнее сообщение Гость
  • Как вывести настольное приложение на передний план из веб-приложения через приложение в трее [дубликат]
    Anonymous » » в форуме C#
    0 Ответы
    50 Просмотры
    Последнее сообщение Anonymous
  • Установить значок в трее, чтобы он всегда отображался
    Anonymous » » в форуме C#
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Как в Pop!_OS 22.04 LTS использовать Java для отображения значка в трее
    Anonymous » » в форуме JAVA
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Как в Pop!_OS 22.04 LTS использовать Java для отображения значка в трее
    Anonymous » » в форуме Linux
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»