Windows下用Python自动化Chrome窗口置顶与新建标签页

Windows下用Python自动化Chrome窗口置顶与新建标签页

环境准备

windows安装winsdk,然后使用其自带的inspect,相关官网:辅助功能工具 - 检查、Windows SDK 下载存档。检查(Inspect.exe)是基于 Windows 的工具,可以选择任何 UI 元素并查看其辅助功能数据。 可以查看Microsoft UI 自动化属性和控件模式以及Microsoft活动辅助功能(MSAA)属性。 检查还可以测试 UI 自动化树中自动化元素的导航结构以及Microsoft活动辅助功能层次结构中的可访问对象

git-bash下载网站:Git

miniconda下载:Miniconda

需求与效果

在 Windows 上实现一键操作:

  1. 打开(或激活)Google Chrome 浏览器;
  2. 将窗口**置顶**(TopMost),且支持再次运行时**取消置顶**(可切换);
  3. 自动新建一个标签页。

实现方式:conda 环境 + 单个 Python 脚本,仅依赖 =pywin32=。

方案概览

运行脚本
   │
   ├─ 1. 查找 Chrome 主窗口(EnumWindows + 类名 Chrome_WidgetWin_1)
   │      └─ 未找到 → 定位 chrome.exe 并启动,轮询等待窗口出现
   │
   ├─ 2. 激活窗口到前台(ShowWindow + SetForegroundWindow)
   │
   ├─ 3. 读取 GWL_EXSTYLE,检查 WS_EX_TOPMOST (0x8) 标志位
   │      ├─ 已置顶 → SetWindowPos(HWND_NOTOPMOST) → 取消置顶
   │      └─ 未置顶 → SetWindowPos(HWND_TOPMOST)   → 置顶
   │
   └─ 4. keybd_event 发送 Ctrl+T 新建标签页

新建标签页选择 Ctrl+T 快捷键而非 UIA 点击“新标签页”按钮: 快捷键不受 Chrome 界面语言、版本和 DPI 缩放影响,更稳定。 (UIA 检查显示该按钮 ClassName 为 =TabStripControlButton=,支持 InvokePattern, 如需精确点击也可走 UIA 路线。)

环境准备:conda 创建独立环境

1
2
3
4
5
6
7
# 首次使用新版 conda 需先接受渠道服务条款(ToS)
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/msys2

# 创建环境(pywin32 走 conda 仓库,免去 pywin32_postinstall 的麻烦)
conda create -n chrome_auto python=3.12 pywin32 -y

核心脚本 chrome_newtab.py

文件位置:=D:\temp\chrome_newtab.py=

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# -*- coding: utf-8 -*-
"""
chrome_newtab.py
打开/激活 Google Chrome,切换窗口置顶状态,并新建一个标签页 (Ctrl+T)。

用法:
    python chrome_newtab.py
    首次运行:置顶窗口 + 新建标签页
    再次运行:取消置顶 + 新建标签页
"""

import os
import subprocess
import sys
import time

import win32api
import win32con
import win32gui

CHROME_CLASS = "Chrome_WidgetWin_1"

CHROME_PATHS = [
    os.path.expandvars(r"%ProgramFiles%\Google\Chrome\Application\chrome.exe"),
    os.path.expandvars(r"%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe"),
    os.path.expandvars(r"%LocalAppData%\Google\Chrome\Application\chrome.exe"),
]


def find_chrome_exe():
    for path in CHROME_PATHS:
        if os.path.isfile(path):
            return path
    return None


def find_chrome_window():
    """返回第一个可见的 Chrome 主窗口句柄,找不到返回 0"""
    result = []

    def callback(hwnd, _):
        if win32gui.IsWindowVisible(hwnd) and win32gui.GetClassName(hwnd) == CHROME_CLASS:
            if win32gui.GetWindowText(hwnd):  # 主窗口标题非空
                result.append(hwnd)
        return True

    win32gui.EnumWindows(callback, None)
    return result[0] if result else 0


def wait_for_window(timeout=10.0):
    deadline = time.time() + timeout
    while time.time() < deadline:
        hwnd = find_chrome_window()
        if hwnd:
            return hwnd
        time.sleep(0.3)
    return 0


def bring_to_foreground(hwnd):
    if win32gui.IsIconic(hwnd):
        win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
    try:
        win32gui.SetForegroundWindow(hwnd)
    except Exception:
        # 绕过前台锁定:先按一下 Alt
        win32api.keybd_event(win32con.VK_MENU, 0, 0, 0)
        win32api.keybd_event(win32con.VK_MENU, 0, win32con.KEYEVENTF_KEYUP, 0)
        win32gui.SetForegroundWindow(hwnd)


def toggle_topmost(hwnd):
    """切换置顶状态,返回切换后的状态(True=已置顶)"""
    ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
    is_topmost = bool(ex_style & win32con.WS_EX_TOPMOST)
    flag = win32con.HWND_NOTOPMOST if is_topmost else win32con.HWND_TOPMOST
    win32gui.SetWindowPos(
        hwnd, flag, 0, 0, 0, 0,
        win32con.SWP_NOMOVE | win32con.SWP_NOSIZE,
    )
    return not is_topmost


def send_ctrl_t():
    win32api.keybd_event(win32con.VK_CONTROL, 0, 0, 0)
    win32api.keybd_event(ord("T"), 0, 0, 0)
    win32api.keybd_event(ord("T"), 0, win32con.KEYEVENTF_KEYUP, 0)
    win32api.keybd_event(win32con.VK_CONTROL, 0, win32con.KEYEVENTF_KEYUP, 0)


def main():
    hwnd = find_chrome_window()
    if not hwnd:
        exe = find_chrome_exe()
        if not exe:
            print("[错误] 未找到 chrome.exe,请确认已安装 Google Chrome。")
            sys.exit(1)
        print(f"[信息] Chrome 未运行,正在启动: {exe}")
        subprocess.Popen([exe])
        hwnd = wait_for_window(10)
        if not hwnd:
            print("[错误] 等待 Chrome 窗口超时。")
            sys.exit(1)
    else:
        print(f"[信息] 检测到 Chrome 窗口 hwnd=0x{hwnd:08X}")

    bring_to_foreground(hwnd)
    time.sleep(0.3)  # 等待窗口获得焦点

    now_topmost = toggle_topmost(hwnd)
    print("[信息] 窗口已置顶" if now_topmost else "[信息] 窗口已取消置顶")

    time.sleep(0.2)
    send_ctrl_t()
    print("[信息] 已发送 Ctrl+T,新建标签页完成。")


if __name__ == "__main__":
    main()

关键 Win32 API 说明

API / 常量作用
EnumWindows + 类名 Chrome_WidgetWin_1枚举并定位 Chrome 主窗口句柄
IsIconic / ShowWindow(SW_RESTORE)窗口最小化时先还原
SetForegroundWindow把窗口激活到前台(失败时用 Alt 键绕过前台锁定)
GetWindowLong(GWL_EXSTYLE)读取扩展样式,检测 WS_EX_TOPMOST (0x8) 判断当前是否置顶
SetWindowPos(HWND_TOPMOST / HWND_NOTOPMOST)设置/取消置顶,配合 SWP_NOMOVE \vert SWP_NOSIZE 不改变位置尺寸
keybd_event模拟按键发送 Ctrl+T 新建标签页

使用方法

1
2
3
4
5
6
# 方式一:激活环境后运行
conda activate chrome_auto
python D:/temp/chrome_newtab.py

# 方式二:免激活直接运行
conda run -n chrome_auto --no-capture-output python D:/temp/chrome_newtab.py

行为对照表:

场景行为
Chrome 未运行自动启动 → 置顶 → 新建标签页
已运行、未置顶激活前台 → 置顶 → 新建标签页
已运行、已置顶激活前台 → 取消置顶 → 新建标签页

测试验证

在 Chrome 已运行(主窗口 =hwnd=0x0006022E=)的情况下连续运行两次:

# 第 1 次
[信息] 检测到 Chrome 窗口 hwnd=0x0006022E
[信息] 窗口已置顶
[信息] 已发送 Ctrl+T,新建标签页完成。

# 第 2 次
[信息] 检测到 Chrome 窗口 hwnd=0x0006022E
[信息] 窗口已取消置顶
[信息] 已发送 Ctrl+T,新建标签页完成。

检测到的句柄与 UIA 工具抓取的 0x0006022E 一致,置顶/取消切换正常。

后续可扩展

  • *命令行参数*:增加 --on / --off / =–toggle=,实现强制置顶、强制取消或仅切换而不新建标签页;
  • *一键批处理*:编写 chrome_newtab.bat 双击运行:

    1
    2
    3
    
    @echo off
    call conda activate chrome_auto
    python D:\temp\chrome_newtab.py
  • *UIA 方案*:改用 uiautomation 库调用“新标签页”按钮的 InvokePattern,实现不依赖键盘焦点的精确点击。