【问题标题】:How to run a file and get the hwnd using win32 in python?如何在python中使用win32运行文件并获取hwnd?
【发布时间】:2013-12-12 02:13:32
【问题描述】:

我知道使用 os.startfile('....') 或 os.system('....') 可以运行文件,例如 *.pdf、*.mp4 等,但它无法获得该文件的 hwnd。 (我必须知道 hwnd 才能控制窗口,例如移动、调整大小或关闭它)

当然,我可以通过win32gui.FindWindow(None,"file name")获取hwnd,但是如果有两个同名的窗口,就不能单独获取hwnd了。

有没有函数可以在win32中运行文件并获取其hwnd?

像这样:

hwnd=win32.function("file dir/file name") // run a file like os.startfile(...)

//hwnd=-1 if failed

//hwnd=1234567 if successful

然后我可以运行多个文件并毫无问题地获取它们的 hwnd。

提前致谢。

【问题讨论】:

    标签: python winapi


    【解决方案1】:

    首先,“hwnd”是一个模棱两可的概念。一个进程可以没有窗口,也可以有 3000 个窗口。

    但是假设您碰巧正在运行一个始终只有 1 个窗口的程序,并且您需要知道哪些窗口属于您实际启动的进程,而不是例如已经运行的同一进程的另一个实例。 (否则你可以只按标题和类别搜索。)

    因此,您需要一些方法来引用该过程。如果您使用的是os.systemos.startfile,则无法执行此操作,因此您会被卡住。这只是使用subprocess 模块的众多原因之一:

    p = subprocess.Popen(args)
    pid = p.pid
    

    现在,您只需 enumerate all top-level windows,然后是 get the PID for each,然后检查哪一个匹配。

    假设您安装了pywin32,并且您使用的是 Python 3.x,它看起来像这样:

    def find_window_for_pid(pid):
        result = None
        def callback(hwnd, _):
            nonlocal result
            ctid, cpid = win32process.GetWindowThreadProcessId(hwnd)
            if cpid == pid:
                result = hwnd
                return False
            return True
        win32gui.EnumWindows(callback, None)
        return result
    

    在 Python 2.x 中,没有nonlocal,所以你需要一些其他的方法来从你的回调中获取值到外部函数,比如一个可变虚拟变量的闭包(比如result = [None],然后设置@ 987654334@ 而不是 result)。


    但请注意,这很容易失败,因为当您第一次启动该进程时,它可能直到几毫秒后才会有窗口。如果没有一些在父子之间同步的方法,真的没有办法解决这个问题。 (你可以通过睡眠一秒钟来破解它,但这与任何尝试睡眠而不是同步的问题相同——大多数情况下,它会太长,减少无缘无故地影响代码的响应能力/性能,偶尔,当计算机繁忙时,它会太短而失败。)

    真正解决这个问题的唯一方法是使用pywin32create the process,而不是使用标准的Python 代码。然后你就有了进程的句柄。这意味着您可以wait for the child to start its window loop,然后仅枚举该进程的窗口。

    【讨论】:

    • 感谢这篇优雅实用的文章。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 2011-01-21
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多