[英]How to run a file and get the hwnd using win32 in python?
I know using os.startfile('....') or os.system('....') can run a file, for example, *.pdf, *.mp4 and so on, but it can't get the hwnd of that file. 我知道使用os.startfile('....')或os.system('....')可以运行文件,例如* .pdf,*。mp4等,但不能获取该文件的hwnd。 (I have to know the hwnd to control the window, for instance, move, resize, or close it)
(我必须知道hwnd来控制窗口,例如,移动,调整大小或关闭它)
Of course, I can get the hwnd by win32gui.FindWindow(None,"file name"), however, it can't get hwnd separately if there are two windows which have the same name. 当然,我可以通过win32gui.FindWindow(None,“ file name”)获得hwnd,但是,如果有两个具有相同名称的窗口,则无法分别获取hwnd。
Is there a function can run a file and get its hwnd in win32? 是否有功能可以运行文件并在win32中获取其hwnd?
Like this: 像这样:
hwnd=win32.function("file dir/file name") // run a file like os.startfile(...)
//hwnd=-1 if failed
//hwnd=1234567 if successful
and then I can run multiple files and get their hwnd without any problem. 然后我可以运行多个文件并毫无问题地获取它们的hwnd。
Thanks in advance. 提前致谢。
First, "the hwnd" is an ambiguous concept. 首先,“ hwnd”是一个模棱两可的概念。 A process can have no windows, or 3000 windows.
一个进程可以没有窗口,也可以没有3000个窗口。
But let's assume you happen to be running a program that always has exactly 1 window, and you need to know which windows belongs to the process you actually launched rather than, say, another instance of the same process already running. 但是,让我们假设您正在运行的程序始终只有一个窗口,并且您需要知道哪些窗口属于您实际启动的进程,而不是已经运行的同一进程的另一个实例。 (Otherwise you could just search by title and class.)
(否则,您可以按标题和类别进行搜索。)
So, you need some way to refer the process. 因此,您需要某种方式来引用该过程。 If you're using
os.system
or os.startfile
, you have no way to do that, so you're stuck. 如果您使用的是
os.system
或os.startfile
,则无法执行此操作,因此会陷入困境。 This is just one of the many, many reasons to use the subprocess
module instead: 这只是代替使用
subprocess
模块的众多原因之一:
p = subprocess.Popen(args)
pid = p.pid
Now, you just enumerate all top-level windows , then get the PID for each , and check which one matches. 现在,您只枚举所有顶级窗口 ,然后获取每个 窗口 的PID并检查匹配的窗口 。
Assuming you have pywin32
installed, and you're using Python 3.x, it looks like this: 假设您已经安装了
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
In Python 2.x, there's no nonlocal
, so you need some other way to get the value from your callback to the outer function, like a closure around a mutable dummy variable (like result = [None]
, then set result[0]
instead of result
). 在Python 2.x中,没有
nonlocal
变量,因此您需要其他方法来将值从回调函数获取到外部函数,例如围绕可变变量的闭包(例如result = [None]
,然后设置result[0]
而不是result
)。
But note that this can easily fail, because when you first launch the process, it probably doesn't have a window until a few milliseconds later. 但是请注意,这很容易失败,因为当您首次启动该过程时,它可能直到几毫秒后才没有窗口。 Without some means of synchronizing between the parent and child, there's really no way around this.
如果没有父母与孩子之间进行同步的任何手段,那么实际上是无法解决的。 (You can hack it by, say, sleeping for a second, but that has the same problem as any attempt to sleep instead of synchronizing—most of the time, it'll be way too long, reducing the responsiveness/performance of your code for no reason, and occasionally, when the computer is busy, it'll be too short and fail.)
(你可以通过破解,比方说,睡了一秒钟,但具有相同的问题,因为任何试图入睡,而不是同步,大部分的时间,这将是时间太长,减少你的代码的响应/性能无缘无故,偶尔,当计算机繁忙时,它会变得太短而失败。)
The only way to really solve this is to use pywin32
to create the process instead of using standard Python code. 真正解决此问题的唯一方法是使用
pywin32
创建过程,而不是使用标准的Python代码。 Then you have a handle to the process. 然后,您可以处理该过程。 This means you can wait for the child to start its window loop , then enumerate just that process's windows.
这意味着您可以等待孩子开始其窗口循环 ,然后仅枚举该进程的窗口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.