从 PID 设置活动/前景 window
Set Active / Foreground window from PID
我正在尝试将一个程序(已知 PID)设置为顶部/活动/前景(不确定哪个最合适)。
PID设置为windows进程PID
handle = win32api.OpenProcess( win32con.PROCESS_ALL_ACCESS,
False, pid)
win32gui.SetForegroundWindow(handle)
win32gui.SetActiveWindow(handle)
我要么得到:
pywintypes.error: (1400, 'SetForegroundWindow', 'Invalid window Handle.')
pywintypes.error: (1400, 'SetActiveWindow', 'Invalid window handle.')
我意识到这是处理程序中的一个问题,但我不确定我应该如何正确获取工作处理程序。
OpenProcess 函数:
如果函数成功,return 值是指定 process.and 的打开句柄,它可用于任何需要进程句柄的函数。
SetForegroundWindow 函数:
它的参数是 window 的句柄,应该被激活并带到前台。
所以你需要这样的翻译:
HWND h = ::GetTopWindow(0 );
while ( h )
{
DWORD pid;
DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
if ( pid == /*your process id*/ )
{
// here h is the handle to the window
break;
}
h = ::GetNextWindow( h , GW_HWNDNEXT);
}
一个python版本:
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
一些注意事项:
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.)
真正解决这个问题的唯一方法是使用 pywin32 创建进程,而不是使用标准 Python 代码。然后你就掌握了这个过程。这意味着您可以等待子进程开始其 window 循环,然后仅枚举该进程的 windows.
这个工作可以用pywinauto来完成:
from pywinauto import Application
app = Application().connect(process=<pid>)
app.top_window().set_focus()
但它可能不适用于最小化的应用程序。
我正在尝试将一个程序(已知 PID)设置为顶部/活动/前景(不确定哪个最合适)。
PID设置为windows进程PID
handle = win32api.OpenProcess( win32con.PROCESS_ALL_ACCESS,
False, pid)
win32gui.SetForegroundWindow(handle)
win32gui.SetActiveWindow(handle)
我要么得到:
pywintypes.error: (1400, 'SetForegroundWindow', 'Invalid window Handle.')
pywintypes.error: (1400, 'SetActiveWindow', 'Invalid window handle.')
我意识到这是处理程序中的一个问题,但我不确定我应该如何正确获取工作处理程序。
OpenProcess 函数:
如果函数成功,return 值是指定 process.and 的打开句柄,它可用于任何需要进程句柄的函数。
SetForegroundWindow 函数:
它的参数是 window 的句柄,应该被激活并带到前台。
所以你需要这样的翻译:
HWND h = ::GetTopWindow(0 );
while ( h )
{
DWORD pid;
DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
if ( pid == /*your process id*/ )
{
// here h is the handle to the window
break;
}
h = ::GetNextWindow( h , GW_HWNDNEXT);
}
一个python版本:
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
一些注意事项:
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.)
真正解决这个问题的唯一方法是使用 pywin32 创建进程,而不是使用标准 Python 代码。然后你就掌握了这个过程。这意味着您可以等待子进程开始其 window 循环,然后仅枚举该进程的 windows.
这个工作可以用pywinauto来完成:
from pywinauto import Application
app = Application().connect(process=<pid>)
app.top_window().set_focus()
但它可能不适用于最小化的应用程序。