如何在后台运行python程序以保持活动窗口相同 [英] How to run python program in background to keep active window the same

查看:118
本文介绍了如何在后台运行python程序以保持活动窗口相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个程序,将前景窗口更改为监视器尺寸的85%,并且要成功运行,前景窗口需要保持不变.

I have written a program that will change the foreground window to 85% of the monitor's dimensions and to run successfully the foreground window needs to remain the same.

我已将python脚本(.pyw)放入批处理文件(正在运行pythonw)中,并在桌面上创建了该批处理文件的快捷方式,并具有快速运行该快捷方式的快捷方式.我还让它运行最小化的批处理文件,但仍将前台窗口切换到最小化的命令提示符.

I have put the python script (.pyw) into a batch file (running pythonw) and created a shortcut to the batch file on the desktop with a shortcut to run it quickly. I also made it run the batch file minimized but it still switches the foreground window to the minimized command prompt.

按照下面的python代码,我正在使用pywin32进行窗口操作.我得到了显示器的信息,因为我有三个显示器设置,因此需要考虑相应显示器的坐标.

Per the python code below I am using pywin32 for the window manipulation. I get the information for the monitor because I have a three monitor setup so need to take into account the coordinates of the appropriate monitor.

#! python

import win32api
import win32gui
import win32con

monitors = win32api.EnumDisplayMonitors()
monitorsDict = {}
hwnd = win32gui.GetForegroundWindow()
currentWindowDimensions = win32gui.GetWindowRect(hwnd)
monitorInFocus = str(win32api.MonitorFromWindow(hwnd))

for i in range(len(monitors)):
    monitorsDict[str(monitors[i][0])] = monitors[i][2]

maxWidth = (monitorsDict[monitorInFocus][2]-monitorsDict[monitorInFocus][0]) * .85
maxHeight = (monitorsDict[monitorInFocus][3]-monitorsDict[monitorInFocus][1]) * .85
x = int(currentWindowDimensions[0])
y = int(currentWindowDimensions[1])
newWidth = int(maxWidth + x)
newHeight = int(maxHeight + y)
newDimensions = (x, y, newWidth, newHeight)

win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, x, y, newWidth, newHeight, 0)

批处理文件如下:

C:\path\to\pythonw\executable\pythonw.exe C:\path\to\pyw\script\WindowSizing.pyw

给我的印象是,如果我运行pythonw而不是python,它将在后台运行脚本而无需打开命令提示符窗口,但这似乎没有发生.由于命令提示符是前景窗口,因此脚本会更改命令提示符窗口的大小,然后将其关闭,从而不会更改我要调整大小的窗口.

I was under the impression that if I run pythonw rather than python it would run the script in the background without opening a command prompt window but this does not appear to be happening. Because the command prompt is the foreground window the script changes the size of the command prompt window and then closes it resulting in no change to the window I wanted to resize.

在pywin32模块中是否有东西可以让我获取上一个前景窗口的句柄?另外,是否有一种方法可以静默运行python脚本,从而使前台窗口不发生变化?

Is there something in the pywin32 module that would allow me to get the handle for the previous foreground window? Alternatively, is there a way to run the python script silently so the foreground window does not change?

推荐答案

尽管 pythonw 确实在后台运行脚本而不打开命令提示符窗口,但批处理文件却可以运行(即使此窗口是最小化).因此,您必须在执行批处理文件之前找到处于活动状态的窗口.
我们使用 EnumWindows 函数来遍历我们正常(即可见且带有标题)的窗口.上一个窗口是枚举中的第二个窗口.但是,如果您从批处理文件运行python脚本,则命令提示符窗口(如上所述)将是前一个窗口,因此我们要查找的是枚举中的第三个窗口.

Although pythonw does run the script in the background without opening a command prompt window, your batch file does (even if this window is minimized). So you'll have to find the window that was active before your batch file was executed.
We use the EnumWindows function to iterate over our normal (i.e. visible and with a title) windows. The previous window is the second one in the enumeration. However, if you run the python script from a batch file, the command prompt window (as explained above) will be the previous window, so the one we're looking for is the third one in the enumeration.

#! python

import win32api
import win32gui
import win32con

monitors = win32api.EnumDisplayMonitors()
monitorsDict = {}

window_counter = [0]
def enumWindowsProc(hwnd, param):
    if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowTextLength(hwnd) > 0:
        window_counter[0] += 1
        print(win32gui.GetWindowText(hwnd))
        if window_counter[0] == 3:
           window_counter[0] = hwnd
           return False
    return True

try:
   win32gui.EnumWindows(enumWindowsProc,window_counter)
except:
   pass

hwnd = window_counter[0]
currentWindowDimensions = win32gui.GetWindowRect(hwnd)
monitorInFocus = str(win32api.MonitorFromWindow(hwnd))

for i in range(len(monitors)):
    monitorsDict[str(monitors[i][0])] = monitors[i][2]

maxWidth = (monitorsDict[monitorInFocus][2]-monitorsDict[monitorInFocus][0]) * .85
maxHeight = (monitorsDict[monitorInFocus][3]-monitorsDict[monitorInFocus][1]) * .85
x = int(currentWindowDimensions[0])
y = int(currentWindowDimensions[1])
newWidth = int(maxWidth + x)
newHeight = int(maxHeight + y)
newDimensions = (x, y, newWidth, newHeight)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, x, y, newWidth, newHeight, 0)

EnumWindows 调用传递给它的回调函数,直到返回 False .不幸的是,win32实现中存在一个错误:回调返回 False 时, EnumWindows 返回 0 ,而此 0 是错误地将其视为错误,并且python会引发运行时错误.一种解决方法是忽略此错误(如此处所示),或者只是从不返回 False ,从而枚举窗口列表直到最后,尽管我们已经找到了窗口.

EnumWindows calls the callback function pass to it until this returns False. Unfortunately there's a bug in the win32 implementation: when the callback returns False, EnumWindows return 0 and this 0 is mistakenly considered an error and python will raise a run time error. A workaround is ignoring this error (as shown here) or just never return False and thus enumerate the windows list till the very end although we've already found our window.

没有使用批处理文件,而是一种更优雅的方式来调用脚本而无需创建额外的批处理文件:在桌面的快捷方式中,您只需插入一行 C:\ path \ to \pythonw \ executable \ pythonw.exe C:\ path \ to \ pyw \ script \ WindowSizing.pyw 作为目标.但是请记住,在这种情况下,我们需要查找窗口号2而不是3,因此它将是 C:\ path \ to \ pythonw \ executable \ pythonw.exe C:\ path \ to \ pyw \ script\ WindowSizing.pyw .

Instead of using a batch file, there's a more elegant way to invoke your script without creating an extra batch file: in the shortcut on your desktop, you can just insert the one line C:\path\to\pythonw\executable\pythonw.exe C:\path\to\pyw\script\WindowSizing.pyw as the target. But remember, in this case we need to look for window number 2 instead of 3, so it'll be C:\path\to\pythonw\executable\pythonw.exe C:\path\to\pyw\script\WindowSizing.pyw.

我在Windows 7上测试了这两种方法(批处理文件和直接快捷方式目标),并且都可以通过快捷键或单击桌面上的图标来正常运行.

I tested both approaches (batch file and direct shortcut target) on Windows 7 and both work fine, invocated by short cut key or by clicking on the icon on the desktop.

这篇关于如何在后台运行python程序以保持活动窗口相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆