用户：但是桌面端的一直说有uipi无法绕过
助手：## 🔒 UIPI（UI 权限隔离）的真相

**UIPI 确实无法完全绕过**，但**可以用底层 API 模拟硬件输入来操作**。

## 🎯 UIPI 是什么

```
┌─────────────────────────────────────────────┐
│ Windows UIPI (Vista+)                       │
│                                             │
│ 高完整性进程（管理员）                      │
│   └─ 窗口 A                                  │
│       ↓ ❌ 拒绝接收来自 ↓                   │
│   低完整性进程（标准用户）                  │
│       └─ Hermes Agent                        │
│                                             │
│ 结果：uiautomation/pyautogui 找不到/无法操作│
└─────────────────────────────────────────────┘
```

## ✅ 3 个实战方案（按可靠性排序）

### 方案 1：底层 `SendInput` API（最可靠 ⭐）
**原理**：模拟真实的硬件输入事件（鼠标/键盘），不依赖窗口消息路由。

```python
import ctypes
from ctypes import wintypes

user32 = ctypes.windll.user32

# 定义 INPUT 结构体
class MOUSEINPUT(ctypes.Structure):
    _fields_ = [
        ("dx", wintypes.LONG),
        ("dy", wintypes.LONG),
        ("mouseData", wintypes.DWORD),
        ("dwFlags", wintypes.DWORD),
        ("time", wintypes.DWORD),
        ("dwExtraInfo", ctypes.POINTER(wintypes.ULONG)),
    ]

class INPUT(ctypes.Structure):
    _fields_ = [("type", wintypes.DWORD), ("mi", MOUSEINPUT)]

# 鼠标移动
def send_mouse_move(x, y):
    inp = INPUT(type=0, mi=MOUSEINPUT(dx=x, dy=y, mouseData=0, dwFlags=0x0001, time=0, dwExtraInfo=None))
    user32.SendInput(1, ctypes.byref(inp), ctypes.sizeof(INPUT))

# 鼠标点击（左键）
def send_mouse_click(x, y):
    send_mouse_move(x, y)
    # DOWN
    inp = INPUT(type=0, mi=MOUSEINPUT(dx=x, dy=y, mouseData=0, dwFlags=0x0002, time=0, dwExtraInfo=None))
    user32.SendInput(1, ctypes.byref(inp), ctypes.sizeof(INPUT))
    # UP
    inp = INPUT(type=0, mi=MOUSEINPUT(dx=x, dy=y, mouseData=0, dwFlags=0x0004, time=0, dwExtraInfo=None))
    user32.SendInput(1, ctypes.byref(inp), ctypes.sizeof(INPUT))

# 键盘输入
def send_key(char):
    # VK_CODE 转换 + SendInput
    pass
```

✅ **绕过 UIPI**，因为这是硬件级输入  
⚠️ **缺点**：看不到窗口内容（要靠 OCR 或事先记录坐标）

---

### 方案 2：同权限级别运行（最简单）
让 Hermes 和目标程序都在**同一权限级别**：

```powershell
# 选项 A：两者都用管理员
Start-Process powershell -Verb RunAs
# 在管理员 PowerShell 里启动 Hermes
python C:\Users\xxx\.hermes\run.py

# 选项 B：两者都用标准用户
# 关掉 Hermes 的"以管理员运行"属性
```

✅ **简单有效**  
⚠️ **限制**：目标程序可能必须用管理员（如某些企业管理软件）

---

### 方案 3：商业 RPA 工具（最强大）
- **UiPath**（企业级，有免费社区版）
- **Power Automate Desktop**（微软免费）
- **AutoHotkey**（开源，Windows 老牌）

```ahk
; AutoHotkey 示例 - 完全绕过 UIPI
#SingleInstance Force
SendMode Input

; 点击坐标
Click, 500, 300
; 输入文字
Send, Hello World{Enter}
; 截图找图
ImageSearch, FoundX, FoundY, 0, 0, 1920, 1080, send_button.png
if (ErrorLevel = 0)
    Click, %FoundX%, %FoundY%
```

✅ **完全绕过 UIPI**（用 SendInput）  
✅ **自带截图找图能力**（ImageSearch）  
✅ **可被 Python 调用**（subprocess）

---

## 🎯 推荐组合方案

```
┌─────────────────────────────────────────┐
│  Windows Hermes Agent                    │
│                                          │
│  Python 脚本层                           │
│   └─ pyautogui（高权限级别匹配）         │
│   └─ SendInput ctypes（UIPI 场景）       │
│                                          │
│  桥接层                                  │
│   └─ AutoHotkey（UIPI 终极绕过）         │
│                                          │
│  目标应用层                              │
│   └─ 微信/钉钉/ERP（任意权限）          │
└─────────────────────────────────────────┘
```

**3 层兜底**：
1. **同权限级别** → pyautogui 工作 → 90% 场景搞定
2. **SendInput** → 绕过 UIPI → 99% 场景搞定
3. **AutoHotkey 桥接** → 终极方案 → 100% 场景搞定

---

## 📋 「鼎+文件桥」具体方案

### 推荐：SendInput + OCR 组合
```python
import ctypes
from PIL import ImageGrab
import pytesseract  # OCR 库

class WeChatAutoBot:
    def __init__(self):
        self.user32 = ctypes.windll.user32
    
    def find_and_click(self, image_path):
        """截图找图 + 点击"""
        # 1. 截图
        screenshot = ImageGrab.grab()
        screenshot.save("/tmp/screen.png")
        
        # 2. 用 pyautogui 的 locateOnScreen
        location = pyautogui.locateOnScreen(image_path, confidence=0.8)
        if location:
            center = pyautogui.center(location)
            # 3. 用 SendInput 点击（绕过 UIPI）
            self.send_click(center.x, center.y)
            return True
        return False
    
    def send_text(self, text):
        """发送文字"""
        for char in text:
            self.user32.keybd_event(self.vk_code(char), 0, 0, 0)
            self.user32.keybd_event(self.vk_code(char), 0, 2, 0)
            time.sleep(0.02)
```

---

## 🔥 实测建议：先诊断，再选方案

让我帮你做个 **UIPI 诊断测试**：

```powershell
# 在 Windows 上跑这个
python -c "
import uiautomation as auto
try:
    wechat = auto.WindowControl(Name='微信')
    if wechat.Exists(maxSearchSeconds=2):
        print('✅ 找到微信窗口')
        btn = wechat.ButtonControl(Name='发送')
        if btn.Exists(maxSearchSeconds=2):
            print('✅ 找到发送按钮')
            btn.Click()
            print('✅ 点击成功')
        else:
            print('❌ 找不到按钮（可能是 UIPI）')
    else:
        print('❌ 找不到窗口（UIPI 或窗口未开）')
except Exception as e:
    print(f'❌ 错误: {e}')
"
```

**结果判断**：
| 现象 | 原因 | 解决方案 |
|------|------|---------|
| 全部 ✅ | 没 UIPI 问题 | 直接用 uiautomation |
| 窗口找不到 ❌ | UIPI 阻挡 | 用 SendInput |
| 按钮找不到 ❌ | 控件不标准 | 用 OCR + SendInput |
| 点击无反应 ❌ | 消息被拦截 | 用 SendInput 模拟硬件输入 |

---

## ❓ 你要做什么？

| 选项 | 说明 |
|------|------|
| **A** | 我帮你写完整 Windows GUI 自动化 skill（含 SendInput + UIPI 绕过） |
| **B** | 写「鼎+文件桥」专用脚本（微信发送文件）|
| **C** | 先教你 UIPI 诊断测试（你在 Windows 上跑）|
| **D** | 提供 AutoHotkey 桥接方案 |

要哪个？或者告诉我「鼎+文件桥」具体场景，我直接写 🎯