📅 发布日期:2026年2月6日
© 2026 DREAMVFIA UNION | All Rights Reserved
℗ 2026 DREAMVFIA UNION


前言

在 AI 助手蓬勃发展的今天,如何让 AI 真正「动手」控制我们的电脑成为了一个重要课题。本文将介绍如何通过 OpenClaw 桥接调用 Windows MCP (Model Context Protocol),让你的 AI 助手具备操控 Windows 系统的能力。

一、Windows MCP 简介

Windows MCP 是一个轻量级开源项目,它充当 AI Agents 与 Windows 操作系统之间的桥梁,让 AI 能够执行文件导航、应用控制、UI 交互、QA 测试等任务。
在这里插入图片描述

核心特性

  • 🔧 无缝 Windows 集成 - 原生交互 Windows UI 元素
  • 🤖 兼容任意 LLM - 支持视觉分析但不依赖传统 CV
  • 🛠️ 丰富的 UI 自动化工具集 - 键盘、鼠标、截屏等
  • 实时交互 - 延迟 0.2-0.9 秒
  • 🌐 DOM 模式 - 支持浏览器自动化

二、安装 Windows MCP

方式一:PyPI 安装(推荐)

# 安装 uv 包管理器
pip install uv

# 安装 Windows MCP
uvx windows-mcp

方式二:源码安装

# 克隆仓库
git clone https://github.com/CursorTouch/Windows-MCP.git
cd Windows-MCP

# 安装依赖
uv pip install -e .

依赖检查

# 检查关键依赖
import pyautogui
import pywin32
print("pyautogui:", pyautogui.__version__)
print("pywin32: OK")

三、核心功能实现

3.1 截屏功能

#!/usr/bin/env python3
"""截屏脚本 - 保存到桌面"""
import pyautogui
import os

def take_screenshot(save_path=None):
    """截取屏幕"""
    img = pyautogui.screenshot()
    if not save_path:
        save_path = os.path.expanduser(r'~\Desktop\screenshot.png')
    img.save(save_path)
    return save_path, img.size

# 使用
path, size = take_screenshot()
print(f"截屏已保存: {path}, 尺寸: {size}")

3.2 鼠标点击

#!/usr/bin/env python3
"""点击指定坐标"""
import argparse
import pyautogui

def click(x, y, button='left', clicks=1):
    """点击屏幕坐标
    
    Args:
        x: X 坐标
        y: Y 坐标
        button: 鼠标按钮 ('left', 'right', 'middle')
        clicks: 点击次数
    """
    pyautogui.click(x, y, button=button, clicks=clicks)
    print(f'点击 ({x}, {y}) - {button}键')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--x', required=True, type=int)
    parser.add_argument('--y', required=True, type=int)
    parser.add_argument('--button', default='left')
    args = parser.parse_args()
    click(args.x, args.y, args.button)

3.3 文本输入

#!/usr/bin/env python3
"""输入文本"""
import argparse
import pyautogui

def type_text(text, x=None, y=None, clear=False):
    """输入文本到指定位置
    
    Args:
        text: 要输入的文本
        x: X 坐标(可选)
        y: Y 坐标(可选)
        clear: 是否先清除已有内容
    """
    if x and y:
        pyautogui.click(x, y)
        if clear:
            pyautogui.hotkey('ctrl', 'a')
            pyautogui.press('backspace')
    
    pyautogui.typewrite(text, interval=0.02)
    print(f'输入: {text}')

# 使用示例
type_text("Hello World!", x=100, y=200, clear=True)

3.4 滚动操作

#!/usr/bin/env python3
"""滚动页面"""
import argparse
import pyautogui

def scroll(direction='down', clicks=1):
    """滚动页面
    
    Args:
        direction: 滚动方向 ('up', 'down')
        clicks: 滚动次数
    """
    value = clicks if direction == 'down' else -clicks
    pyautogui.scroll(value)
    print(f'滚动 {direction} {clicks} 次')

# 使用
scroll('down', 3)  # 向下滚3次
scroll('up', 2)    # 向上滚2次

3.5 快捷键执行

#!/usr/bin/env python3
"""执行快捷键"""
import argparse
import pyautogui

def hotkey(*keys):
    """执行快捷键组合
    
    Examples:
        hotkey('ctrl', 'c')      # 复制
        hotkey('alt', 'tab')     # 切换窗口
        hotkey('win', 'r')       # 打开运行
    """
    pyautogui.hotkey(*keys)
    print(f'按下: {"+".join(keys)}')

# 使用
hotkey('ctrl', 'c')   # 复制
hotkey('win', 'r')    # 运行

3.6 应用启动与切换

#!/usr/bin/env python3
"""应用控制"""
import subprocess
import psutil
import os

def launch_app(app_name):
    """启动应用"""
    # 方法1: 通过开始菜单
    apps = get_start_menu_apps()
    matched = find_best_match(app_name, apps.keys())
    if matched:
        subprocess.run(['powershell', f'Start-Process "{apps[matched]}"'])
        return f"启动: {matched}"
    
    # 方法2: 直接运行
    try:
        subprocess.Popen(app_name)
        return f"运行: {app_name}"
    except:
        return f"无法启动: {app_name}"

def get_running_apps():
    """获取运行中的应用列表"""
    apps = []
    for proc in psutil.process_iter(['pid', 'name']):
        try:
            apps.append({
                'pid': proc.info['pid'],
                'name': proc.info['name']
            })
        except:
            pass
    return apps

def switch_to_window(window_title):
    """切换到指定窗口"""
    import win32gui
    hwnds = []
    def enum_callback(hwnd, _):
        if win32gui.IsWindowVisible(hwnd):
            title = win32gui.GetWindowText(hwnd)
            if window_title.lower() in title.lower():
                hwnds.append((hwnd, title))
    win32gui.EnumWindows(enum_callback, None)
    
    if hwnds:
        hwnd, title = hwnds[0]
        win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
        win32gui.SetForegroundWindow(hwnd)
        return f"切换到: {title}"
    return "未找到窗口"

3.7 PowerShell 执行

#!/usr/bin/env python3
"""执行 PowerShell 命令"""
import subprocess
import base64

def execute_powershell(command, timeout=30):
    """执行 PowerShell 命令
    
    Args:
        command: PowerShell 命令
        timeout: 超时时间(秒)
    
    Returns:
        (stdout, stderr, returncode)
    """
    encoded = base64.b64encode(command.encode('utf-16le')).decode('ascii')
    result = subprocess.run(
        ['powershell', '-NoProfile', '-EncodedCommand', encoded],
        capture_output=True,
        timeout=timeout
    )
    return result.stdout, result.stderr, result.returncode

# 使用示例
stdout, stderr, code = execute_powershell('Get-Process | Select -First 5')
print(stdout.decode('utf-8'))

四、OpenClaw 桥接调用

4.1 创建 OpenClaw Skill

skills/windows-mcp/
├── SKILL.md              # 技能说明文档
├── snapshot.py           # 截屏脚本
├── click.py             # 点击脚本
├── type.py              # 输入脚本
├── scroll.py            # 滚动脚本
├── move.py              # 移动脚本
├── shortcut.py          # 快捷键脚本
└── ...

4.2 OpenClaw 调用示例

在 OpenClaw 中通过 exec 工具调用:

# 截屏
exec(command="python skills/windows-mcp/snapshot.py")

# 点击坐标
exec(command="python skills/windows-mcp/click.py --x 100 --y 200")

# 输入文本
exec(command="python skills/windows-mcp/type.py --text 'Hello' --x 500 --y 300")

# 执行快捷键
exec(command="python skills/windows-mcp/shortcut.py --keys 'ctrl+c'")

4.3 完整桥接脚本

#!/usr/bin/env python3
"""
Windows MCP Wrapper for OpenClaw
统一调用接口
"""

import argparse
import pyautogui
import subprocess
import base64
import sys

class WindowsMCPBridge:
    """OpenClaw 与 Windows MCP 的桥接类"""
    
    def __init__(self):
        self.pg = pyautogui
        self.pg.FAILSAFE = False
        self.pg.PAUSE = 0.5
    
    # ========== 鼠标操作 ==========
    
    def click(self, x, y, button='left', clicks=1):
        """点击"""
        self.pg.click(x, y, button=button, clicks=clicks)
        return f'点击 ({x}, {y})'
    
    def double_click(self, x, y):
        """双击"""
        self.pg.doubleClick(x, y)
        return f'双击 ({x}, {y})'
    
    def right_click(self, x, y):
        """右键点击"""
        self.pg.click(x, y, button='right')
        return f'右键 ({x}, {y})'
    
    def move(self, x, y):
        """移动鼠标"""
        self.pg.moveTo(x, y, duration=0.1)
        return f'移动到 ({x}, {y})'
    
    def scroll(self, direction='down', clicks=1):
        """滚动"""
        value = clicks if direction == 'down' else -clicks
        self.pg.scroll(value)
        return f'滚动 {direction} {clicks} 次'
    
    # ========== 键盘操作 ==========
    
    def type(self, text, x=None, y=None, clear=False):
        """输入文本"""
        if x and y:
            self.pg.click(x, y)
            if clear:
                self.pg.hotkey('ctrl', 'a')
                self.pg.press('backspace')
        self.pg.typewrite(text, interval=0.02)
        return f'输入: {text}'
    
    def hotkey(self, *keys):
        """快捷键"""
        self.pg.hotkey(*keys)
        return f'快捷键: {"+".join(keys)}'
    
    def press(self, key):
        """按单个键"""
        self.pg.press(key)
        return f'按键: {key}'
    
    # ========== 截屏 ==========
    
    def screenshot(self, path=None):
        """截屏"""
        img = self.pg.screenshot()
        if not path:
            path = r'~\Desktop\screenshot.png'
        path = self._expand_path(path)
        img.save(path)
        return path, img.size
    
    # ========== 系统操作 ==========
    
    def execute_powershell(self, command, timeout=30):
        """执行 PowerShell"""
        encoded = base64.b64encode(command.encode('utf-16le')).decode('ascii')
        result = subprocess.run(
            ['powershell', '-NoProfile', '-EncodedCommand', encoded],
            capture_output=True,
            timeout=timeout
        )
        return result.stdout.decode('utf-8', errors='ignore')
    
    def launch_app(self, name):
        """启动应用"""
        result = subprocess.run(
            ['powershell', f'Start-Process "{name}"'],
            capture_output=True
        )
        return f'启动: {name}'
    
    # ========== 辅助方法 ==========
    
    def get_screen_size(self):
        """获取屏幕尺寸"""
        return self.pg.size()
    
    def get_position(self):
        """获取鼠标位置"""
        return self.pg.position()
    
    def _expand_path(self, path):
        return os.path.expanduser(path)


# CLI 接口
if __name__ == '__main__':
    bridge = WindowsMCPBridge()
    
    parser = argparse.ArgumentParser(description='Windows MCP Bridge for OpenClaw')
    sub = parser.add_subparsers(dest='cmd', required=True)
    
    # 点击
    p = sub.add_parser('click')
    p.add_argument('--x', required=True, type=int)
    p.add_argument('--y', required=True, type=int)
    p.add_argument('--button', default='left')
    
    # 移动
    p = sub.add_parser('move')
    p.add_argument('--x', required=True, type=int)
    p.add_argument('--y', required=True, type=int)
    
    # 输入
    p = sub.add_parser('type')
    p.add_argument('--text', required=True)
    p.add_argument('--x', type=int)
    p.add_argument('--y', type=int)
    p.add_argument('--clear', action='store_true')
    
    # 滚动
    p = sub.add_parser('scroll')
    p.add_argument('--direction', default='down')
    p.add_argument('--clicks', type=int, default=1)
    
    # 快捷键
    p = sub.add_parser('hotkey')
    p.add_argument('--keys', required=True)
    
    # 截屏
    sub.add_parser('screenshot')
    
    args = parser.parse_args()
    
    if args.cmd == 'click':
        print(bridge.click(args.x, args.y, args.button))
    elif args.cmd == 'move':
        print(bridge.move(args.x, args.y))
    elif args.cmd == 'type':
        print(bridge.type(args.text, args.x, args.y, args.clear))
    elif args.cmd == 'scroll':
        print(bridge.scroll(args.direction, args.clicks))
    elif args.cmd == 'hotkey':
        print(bridge.hotkey(*args.keys.split('+')))
    elif args.cmd == 'screenshot':
        path, size = bridge.screenshot()
        print(f'截屏: {path}, 尺寸: {size}')

五、实用技巧

5.1 获取屏幕坐标

# 实时获取鼠标位置用于调试
import pyautogui
import time

print("移动鼠标到目标位置,3秒后开始...")
time.sleep(3)
x, y = pyautogui.position()
print(f"当前位置: ({x}, {y})")

5.2 等待元素加载

import time
import pyautogui

def wait_for_element(timeout=10):
    """等待用户点击指定位置"""
    print(f"请在 {timeout} 秒内将鼠标移动到目标位置...")
    time.sleep(timeout)
    x, y = pyautogui.position()
    print(f"已记录位置: ({x}, {y})")
    return x, y

5.3 自动化表单填写

def fill_form(fields):
    """填写表单
    
    Args:
        fields: [(x, y, value), ...]
    """
    for x, y, value in fields:
        pyautogui.click(x, y)
        pyautogui.hotkey('ctrl', 'a')
        pyautogui.press('backspace')
        pyautogui.typewrite(value)
        time.sleep(0.2)

# 使用
fill_form([
    (100, 200, "John"),      # 姓名
    (100, 250, "john@email.com"),  # 邮箱
    (100, 300, "123456"),    # 电话
])

5.4 错误处理

import pyautogui
import time

def safe_click(x, y, retries=3):
    """带重试的点击"""
    for i in range(retries):
        try:
            pyautogui.click(x, y)
            return True
        except Exception as e:
            print(f"点击失败 ({i+1}/{retries}): {e}")
            time.sleep(1)
    return False

# 使用截图定位
def find_and_click(image_path, confidence=0.8):
    """查找图片并点击"""
    try:
        location = pyautogui.locateCenterOnScreen(image_path, confidence=confidence)
        if location:
            pyautogui.click(location)
            return True
    except Exception as e:
        print(f"查找失败: {e}")
    return False

5.5 组合操作示例

# 自动打开浏览器并搜索
def browser_search(query):
    """浏览器搜索"""
    # 1. 打开浏览器
    pyautogui.hotkey('win', 'r')
    pyautogui.typewrite('chrome')
    pyautogui.press('enter')
    time.sleep(2)
    
    # 2. 输入搜索内容
    pyautogui.typewrite(query)
    pyautogui.press('enter')

# 自动保存文件
def save_file(filename):
    """保存文件"""
    pyautogui.hotkey('ctrl', 's')
    time.sleep(0.5)
    pyautogui.typewrite(filename)
    pyautogui.press('enter')

六、完整项目结构

DREAMVFIA_Windows_MCP/
├── README.md                    # 项目说明
├── requirements.txt             # 依赖
├── src/
│   ├── __init__.py
│   ├── core/
│   │   ├── __init__.py
│   │   ├── mouse.py            # 鼠标操作
│   │   ├── keyboard.py         # 键盘操作
│   │   ├── screenshot.py       # 截屏
│   │   └── system.py           # 系统操作
│   ├── bridge/
│   │   ├── __init__.py
│   │   └── openclaw_bridge.py  # OpenClaw 桥接
│   └── cli/
│       ├── __init__.py
│       └── main.py             # CLI 入口
├── scripts/
│   ├── snapshot.py
│   ├── click.py
│   ├── type.py
│   └── scroll.py
├── tests/
│   ├── test_mouse.py
│   ├── test_keyboard.py
│   └── test_screenshot.py
└── docs/
    └── CHINESE_GUIDE.md        # 中文指南

七、注意事项

7.1 安全建议

  • ⚠️ 谨慎授权 - AI 自动化可能执行不可逆操作
  • 🔒 沙盒环境 - 重要操作前先在测试环境验证
  • 📝 操作日志 - 记录所有自动化操作便于追溯

7.2 已知限制

  • 某些特殊界面(游戏、全屏视频)可能无法操控
  • 需要 Windows 辅助功能权限
  • 延迟受系统负载影响(0.2-0.9 秒)

7.3 故障排除

# 检查依赖
import pyautogui
import win32gui
import win32con

# 测试截屏
img = pyautogui.screenshot()
print(f"截屏测试: {img.size}")

# 测试窗口
hwnd = win32gui.GetForegroundWindow()
print(f"当前窗口: {win32gui.GetWindowText(hwnd)}")

八、扩展阅读


结语

通过 OpenClaw 桥接 Windows MCP,我们实现了 AI 对 Windows 系统的深度控制能力。这为构建智能助手、自动化办公、测试脚本等场景提供了强大的技术基础。

希望这篇文章对你有所帮助!如果你有任何问题或建议,欢迎在评论区交流。

版权声明
© 2026 DREAMVFIA UNION
℗ 2026 DREAMVFIA UNION
未经书面授权,禁止复制、转载本文内容。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐