Windows系统下如何用Python设置调用的外部应用窗口的大小与位置?
问题描述
我正在尝试进行软件自动化操作,需要用Python启动若干第三方应用程序,并自定义这些应用程序窗口的初始位置与大小。我尝试过用subprocess和pywin32库,通过subprocess.STARTUPINFO()和win32process.STARTUPINFO()设置dwX、dwXSize等参数,但目标应用程序完全无视这些设置。
我试过的代码如下:
使用subprocess的代码
import subprocess import win32con import win32gui import ctypes import time wave = "C:\\Program Files\\LeCroy\\WaveStudio\\WaveStudio.exe" startupinfo = subprocess.STARTUPINFO() startupinfo.dwX = 100 startupinfo.dwy = 100 startupinfo.dwXSize = 400 startupinfo.dwYSize = 600 # startupinfo.dwFlags = win32con.STARTF_USEPOSITION | win32con.STARTF_USESIZE subprocess.Popen(wave, startupinfo=startupinfo)
使用win32process的代码
import win32con import win32process wave = "C:\\Program Files\\LeCroy\\WaveStudio\\WaveStudio.exe" # Set the size and position of the window startupinfo = win32process.STARTUPINFO() startupinfo.dwX = 0 startupinfo.dwY = 0 startupinfo.dwXSize = 200 startupinfo.dwYSize = 300 startupinfo.dwFlags = win32con.STARTF_USEPOSITION | win32con.STARTF_USESIZE # Create a new process with the specified path and window size/position process_information = win32process.CreateProcess( None, wave, None, None, False, win32process.CREATE_NEW_CONSOLE, None, None, startupinfo # 原代码存在拼写错误,修正为startupinfo )
解决方案
很多第三方GUI应用(比如你用到的WaveStudio)会在启动时读取自身配置或保存的窗口状态,直接覆盖STARTUPINFO传入的初始设置。这种情况下,正确的做法是启动应用后,找到窗口句柄再强制调整位置和大小。
核心思路
- 启动应用程序,等待窗口加载完成(需根据应用启动速度设置合理延迟或循环检测)。
- 通过窗口标题、进程ID等方式定位目标窗口的句柄。
- 调用Windows API调整窗口的位置与大小。
代码示例:通过窗口标题调整
import subprocess import win32gui import win32con import time def adjust_window(title, x, y, width, height): # 根据窗口标题查找句柄 hwnd = win32gui.FindWindow(None, title) if not hwnd: print(f"未找到标题为「{title}」的窗口") return # 设置窗口位置与大小,SWP_SHOWWINDOW确保窗口正常显示 win32gui.SetWindowPos( hwnd, win32con.HWND_TOP, x, y, width, height, win32con.SWP_SHOWWINDOW ) # 启动目标应用 wave_path = "C:\\Program Files\\LeCroy\\WaveStudio\\WaveStudio.exe" proc = subprocess.Popen(wave_path) # 等待窗口加载(可根据实际启动速度调整时间) time.sleep(3) # 调整窗口位置与大小(替换为WaveStudio实际窗口标题) adjust_window("WaveStudio", 100, 100, 800, 600)
补充:通过进程ID定位窗口
如果不确定窗口标题,可以通过进程ID过滤窗口:
def get_hwnd_by_pid(pid): hwnd_list = [] def enum_callback(hwnd, extra): if win32gui.GetWindowThreadProcessId(hwnd)[1] == extra: hwnd_list.append(hwnd) return True win32gui.EnumWindows(enum_callback, pid) return hwnd_list[0] if hwnd_list else 0 # 启动后通过进程ID获取窗口句柄 hwnd = get_hwnd_by_pid(proc.pid) if hwnd: win32gui.SetWindowPos(hwnd, win32con.HWND_TOP, 100, 100, 800, 600, win32con.SWP_SHOWWINDOW) else: print("未找到目标进程对应的窗口")
优化:循环检测窗口避免固定延迟
固定延迟可能因环境差异失效,可用循环检测窗口是否存在:
hwnd = 0 timeout = 15 # 最大等待15秒 start_time = time.time() while not hwnd and time.time() - start_time < timeout: hwnd = win32gui.FindWindow(None, "WaveStudio") time.sleep(0.5) if hwnd: win32gui.SetWindowPos(hwnd, win32con.HWND_TOP, 100, 100, 800, 600, win32con.SWP_SHOWWINDOW) else: print("超时未找到目标窗口")
内容的提问来源于stack exchange,提问作者sultan
相关产品推荐
相关产品推荐

