【问题标题】:windows executables corresponding to system tray icons?与系统托盘图标对应的Windows可执行文件?
【发布时间】:2011-09-17 14:10:05
【问题描述】:

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

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

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

但它严重依赖 AHK。

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

谢谢!

【问题讨论】:

    标签: python windows pywin32


    【解决方案1】:

    这是厚厚的 win32 东西。我开始使用 pywin32 编写此代码,但切换到 ctypes 以更好地处理结构。注意,我是在 32 win XP 中写的。您将更改 TBBUTTON def 为 64 位。我不确定 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
    

    【讨论】:

    • 顺便说一句,我将如何访问正在运行的应用程序任务栏。即,显示正在运行的前台应用程序的图标。这些不在系统托盘中。
    • @reckoner,本质上你想要 alt+tab 中的内容? stackoverflow.com/questions/210504/…
    • 感谢您的链接。这让我成为了其中的一部分。我的情况略有不同。
    【解决方案2】:

    在我看来,它更多地依赖于 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 年的书现在不会有太大帮助。

    否则,您可以拨打 ahk 可以拨打的任何电话,但这需要阅读 MSDN... 鉴于您大致了解 AHK 脚本的所需内容,您的工作量将大大减少。但它仍然会很烦人。

    如果您想查看一些有关如何实现 windows api 调用(制作结构、调用函数等)的示例,您可能会发现 Grayhat Python 早期章节很有用。我发现这比大多数直接来自 python-windows 组的材料更有帮助,这无疑让我有点过头了。

    祝你好运

    【讨论】:

    • 感谢您的参考。我会研究灰帽书。 AHK 脚本的问题在于它没有提供获取输出的简单方法。
    猜你喜欢
    • 1970-01-01
    • 2017-10-24
    • 2010-10-31
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多