Windows系统可执行文件对应系统托盘图标?

时间:2011-09-17 14:10:06

标签: python windows pywin32

有没有办法使用Python获取系统托盘(右下角)中所有图标及其相关流程和可执行文件的列表?

这是一个关于如何使用AHK执行此操作的线程:

http://www.autohotkey.com/forum/topic17314.html

但它在很大程度上依赖于AHK。

请注意,我对此在Windows XP / 7中感兴趣

谢谢!

2 个答案:

答案 0 :(得分:2)

这是厚厚的win32东西。我开始使用pywin32编写这个,但切换到ctypes以更好地处理结构。注意,我在32 win XP中写了这个。对于64位,您将更改TBBUTTON def。我不确定UAC会对此做些什么(你可以在另一个进程中分配内存吗?)。

import commctrl, win32con
from ctypes import *

# represent the TBBUTTON structure
# note this is 32 bit, 64 bit padds 4 more reserved bytes
class TBBUTTON(Structure):
    _pack_ = 1
    _fields_ = [
        ('iBitmap', c_int),
        ('idCommand', c_int),
        ('fsState', c_ubyte),
        ('fsStyle', c_ubyte),
        ('bReserved', c_ubyte * 2),
        ('dwData', c_ulong),
        ('iString', c_int),
    ]

# get the handle to the sytem tray
hWnd = windll.user32.FindWindowA("Shell_TrayWnd", None)
hWnd = windll.user32.FindWindowExA(hWnd, None, "TrayNotifyWnd", None)
hWnd = windll.user32.FindWindowExA(hWnd, None, "SysPager", None)
hWnd = windll.user32.FindWindowExA(hWnd, None, "ToolbarWindow32", None)

# get the count of icons in the tray
numIcons = windll.user32.SendMessageA(hWnd, commctrl.TB_BUTTONCOUNT, 0, 0)

# allocate memory within the system tray
pid = c_ulong();
windll.user32.GetWindowThreadProcessId(hWnd, byref(pid))
hProcess = windll.kernel32.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
lpPointer = windll.kernel32.VirtualAllocEx(hProcess, 0, sizeof(TBBUTTON), win32con.MEM_COMMIT, win32con.PAGE_READWRITE)

# init our tool bar button and a handle to it
tbButton = TBBUTTON()
butHandle = c_int()

for i in range(numIcons):
    # query the button into the memory we allocated
    windll.user32.SendMessageA(hWnd, commctrl.TB_GETBUTTON, i, lpPointer)
    # read the memory into our button struct
    windll.kernel32.ReadProcessMemory(hProcess, lpPointer, addressof(tbButton), 20, None)
    # read the 1st 4 bytes from the dwData into the butHandle var
    # these first 4 bytes contain the handle to the button
    windll.kernel32.ReadProcessMemory(hProcess, tbButton.dwData, addressof(butHandle), 4, None)

    # get the pid that created the button
    butPid = c_ulong()
    windll.user32.GetWindowThreadProcessId(butHandle, byref(butPid))

    # i leave it to you to get the process from the pid
    # that should be trivial...
    print butPid

答案 1 :(得分:1)

在我看来,它更依赖于windows的api而不是ahk,这可能只是一个包装器,因为你引用的网站上的参数对于它们的用例来说是愚蠢的 - 例如hWnd,101,0,0,0,0--通常建议使用windows'api struct-type-things;)。我非常怀疑你可以在这里插入和播放任何东西,因为这是一个有点不同寻常的目标,并且非常特定于Windows。如果你想自己实现,你很可能会从Tim Golden的网站上得到很多帮助,如果有人以前做过,我会想象他是:

http://timgolden.me.uk/python/wmi/index.html

Mark Hammond和核心python windows的模块也是合理的搜索词,但不知怎的,直接存在相对较少的文档,而且我认为2000年的这本书现在不会有太多的帮助。 / p>

否则,您可以进行ahk可以进行的任何调用,但这需要阅读MSDN ...鉴于您大致了解AHK脚本的内容,您的努力将会大大减少。但它仍然会令人讨厌。

如果你想看一些如何实现windows api调用(制作struct,调用函数等)的例子,你可能会发现Grayhat Python的早期章节很有用。我发现它比直接来自python-windows组的大多数材料更有帮助,这无疑只是我的头脑。

祝你好运