一键唤醒,随处掌控。
这是一个运行在 Win11 上的 Python/FastAPI 小服务。
你可以通过 Tailscale IP 访问网页,然后启动 apps.json 白名单里的 exe,并传入参数。
网页保留彩色毛玻璃风格,并支持浅色 / 深色两套明暗主题。主题和背景设置保存在浏览器里。本版已优化浅色模式蒙层、修复深色模式背景图显示,并增加手机端适配。
设计原则:不提供任意命令执行,只允许启动配置列表里的
.exe。
ExePilot/
├─ main.py
├─ apps.json
├─ requirements.txt
├─ start.bat
├─ install_deps.bat
├─ install_task_admin.bat
├─ uninstall_task_admin.bat
├─ install_firewall_tailscale_admin.bat
├─ uninstall_firewall_tailscale_admin.bat
└─ static/
├─ index.html
├─ styles.css
└─ app.js
└─ ExePilot.ico
前端设置:
- 自由配置启动列表,保存在
apps.json; - 保彩色毛玻璃视觉风格;
- 支持“浅色主题 / 深色主题”切换;
- 背景图片支持三种方式:
- 输入任意
http/https图片 URL; - 一键使用
https://api.dujin.org/bing/1920.php等脚本; - 选择本地图片作为背景;
- 输入任意
- 手机端适配。
背景配置是纯前端设置,不会写入 apps.json。URL 和主题使用 localStorage 保存;本地图片优先保存在浏览器 IndexedDB 中。
选择一个固定目录,比如:
C:\ExePilot
双击运行:
install_deps.bat
或者手动执行:
cd C:\ExePilot
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt双击运行:
start.bat
默认监听:
0.0.0.0:5201
本机访问:
http://127.0.0.1:5201
远程访问:
http://你的远程IP:5201
管理员身份运行:
install_firewall_tailscale_admin.bat
这会添加规则:
TCP 5201,只允许 remoteip=100.64.0.0/10
管理员身份运行:
install_task_admin.bat
它会创建一个计划任务:
ExePilot
触发条件是当前用户登录时启动。
{
"apps": [
{
"name": "notepad",
"path": "C:\\Windows\\System32\\notepad.exe",
"args": "",
"cwd": null,
"description": "示例:启动记事本。可以删除或替换。",
"enabled": true
}
]
}字段说明:
name:网页命令行使用的名称,例如notepadpath:exe 完整路径args:默认参数cwd:工作目录,可空。为空时默认使用 exe 所在目录description:备注enabled:是否启用
假设配置了:
{
"name": "demo",
"path": "C:\\Program Files\\Demo\\demo.exe"
}网页命令行输入:
demo --mode test --name "hello world"
后端实际启动:
C:\Program Files\Demo\demo.exe --mode test --name "hello world"
建议:
- 不要把 5201 暴露到公网。
- Windows 防火墙只允许 Tailscale 网段访问。
- 只把可信 exe 写进
apps.json。 - 不要改成
shell=True。 - 不要允许网页输入任意 exe 路径直接启动。
关闭程序功能使用 Windows PowerShell 的
Get-CimInstance Win32_Process按完整ExecutablePath匹配,不是简单按进程名杀进程,尽量避免误杀同名 exe。
页面新增“实时屏幕”区域:桌面端跨两列显示,手机端单列显示;页面每 5 秒自动刷新截图,也可以手动刷新。后端使用 Pillow 截取当前 Windows 交互桌面,并压缩为 JPEG 返回。
升级旧环境后请重新运行 1-install_deps.bat,以安装新增的 Pillow 依赖。
“实时屏幕”区域支持第一阶段的轻量远程控制:
- 在截图上单击:服务器桌面左键单击。
- 在截图上双击:服务器桌面左键双击。
- 在截图上右键:服务器桌面右键单击。
- 鼠标悬停在截图上滚轮:服务器桌面同步滚动。
- 文本输入框:将 Unicode 文本发送到服务器当前活动窗口。
- Enter / Esc:向服务器当前活动窗口发送对应按键。
坐标使用归一化坐标传输,并映射到 Windows 虚拟桌面,因此兼容网页缩放和多显示器虚拟桌面。
注意:ExePilot 必须运行在当前交互式 Windows 会话中;受 Windows UIPI 权限隔离影响,普通权限运行的 ExePilot 不能向更高完整性级别(例如“以管理员身份运行”)的窗口注入鼠标或键盘事件。
- Remote mouse and keyboard control now consistently uses the Windows
SendInputAPI. - Added
stop.batto stop the running ExePilot scheduled task and its Python process. - Fixed alignment of the screenshot refresh interval controls.
- Fixed mobile overflow in the custom actions section, including long file paths.
实时屏幕区域新增“全屏”按钮。支持浏览器原生 Fullscreen API,并在不支持任意元素全屏的移动浏览器上自动降级为页面内伪全屏。全屏状态下仍可使用截图单击、双击、右键、滚轮、文本输入、Enter 与 Esc。
- Mobile IME focus now happens synchronously during the screenshot tap/pointer gesture, before any API request.
- Desktop fullscreen keyboard forwarding no longer depends on UI Automation text-field detection.
- Touch-capable Windows PCs are no longer misclassified as mobile devices; mobile detection uses browser mobile signals/user agent.
- Text-field detection now checks both the focused UI Automation element and the element at the remote click point, walking parent controls as a fallback.
- Resolve
RTCPeerConnectionexplicitly fromwindowwith WebKit/Mozilla fallbacks. - Validate the constructor before use and show browser diagnostics instead of an uncaught promise error.
- Move peer creation inside the existing error handling.
- Bump static asset versions to
20260713-webrtc2.
本版默认参数:
最大画面:1920 × 1080(保持原始宽高比)
帧率:15 FPS
H.264 目标码率:6,000,000 bps
H.264 Profile:Baseline
H.264 Level:4.0
编码器:libx264 / veryfast / zerolatency
可以通过环境变量覆盖:
WEBRTC_FPS=15
WEBRTC_MAX_WIDTH=1920
WEBRTC_TARGET_BITRATE=6000000
WEBRTC_MIN_BITRATE=1000000
6 Mbps 是编码器初始目标和上限。WebRTC 接收端在网络条件较差时可通过 REMB 要求临时降低码率,以避免严重卡顿。
本版将 aiortc 固定为 1.14.0,因为 main.py 对该版本的 H.264 编码器做了项目内配置扩展。
- 删除“重新连接”按钮,WebRTC 断线后仍由页面自动重连。
- “全屏”按钮旁新增“显示质量 / 隐藏质量”。
- 质量悬浮层显示编码、分辨率、FPS、接收码率、WebRTC RTT 延迟、抖动和丢包率。
- 悬浮层设置
pointer-events: none,不会拦截远程鼠标点击。 - 进入全屏后隐藏标题栏、连接状态、全屏按钮、控制栏按钮和底部状态,仅保留远程画面;如果进入全屏前开启质量监测,则质量信息继续悬浮在画面左上角。
- 桌面浏览器可按
Esc退出原生全屏。
- 按钮文案改为“显示质量监测 / 隐藏质量监测”。
- 质量监测悬浮窗改为低透明度深色玻璃背景,保留画面可见性,并继续允许鼠标穿透。
- 进入全屏前记录页面滚动位置,退出原生或伪全屏后恢复,避免页面跳到上方。
- 桌面浏览器进入实时屏幕全屏后,点击远程画面即可让 ExePilot 接收键盘。
- 支持普通文字、Enter、Esc、Tab、Backspace、Delete、方向键、F1-F24,以及 Ctrl+A / Ctrl+C / Ctrl+V / Ctrl+X 等组合键。
- 文字剪贴板支持读取远程、写入远程、写入后立即远程粘贴,以及复制到本机浏览器剪贴板。
- 本机文件可上传到
transfers/incoming,随后写入 Windows 的 CF_HDROP 文件剪贴板;“上传并粘贴”会额外向当前远程窗口发送 Ctrl+V。 - 在远程 Windows 资源管理器中复制文件后,可通过“读取远程文件”查看,并通过“下载远程文件”下载;多个文件或目录会自动打包为 ZIP。
- 浏览器安全沙箱不允许网页把远程文件直接塞进本机 Windows 资源管理器的文件剪贴板,因此远程到本机采用下载文件/ZIP 的方式。
本次新增依赖:
python-multipart>=0.0.9
升级后需要重新运行 1-install_deps.bat。
- 桌面键盘改为真实的
keydown / keyup状态转发,不再把每次按键都压成一个瞬时组合键。 - Windows 后端使用扫描码
SendInput,远程输入法、Enter、Tab、方向键及快捷键更接近实体键盘。 - Ctrl / Shift 可以保持按下状态;按住后点击远程画面可在资源管理器中多选文件。
- 退出全屏、切换页面或浏览器失去焦点时自动释放远程修饰键,避免 Ctrl / Shift 卡住。
- 手机中文和 Unicode 文本改用“写入远程剪贴板 + Ctrl+V”,并对输入内容短暂合并后发送。
- 剪贴板操作优先通过 STA PowerShell + Windows Forms Clipboard 执行,原 ctypes 实现作为后备。
- 文件剪贴板使用
SetFileDropList / GetFileDropList,提高与 Windows 资源管理器的兼容性。 - Tailscale HTTP 页面复制文字到本机时,增加旧式
execCommand('copy')后备。
在远程画面上按住鼠标左键或手指并拖动,松开后 ExePilot 会在受控端执行完整的左键按下、移动和释放操作。可用于:
- 资源管理器空白处拖出选择框;
- 拖动文件、窗口和滚动条;
- 按住 Ctrl/Shift 后配合拖拽。
拖动过程中网页会显示本地半透明选择框;移动不足 8px 时仍按普通单击处理。
- 实时屏幕控制栏默认隐藏,可通过“显示控制栏”按钮展开。
- 退出全屏后控制栏仍保持隐藏。
- “发送文本”和“远程剪贴板”两个文本框统一背景、边框、圆角、内边距和聚焦效果。
The WebRTC session now sends Windows default-speaker audio through WASAPI loopback.
Video uses H.264 and audio uses Opus at 48 kHz stereo. Browsers start muted to satisfy
autoplay rules; click 开启声音 once after opening the page. Run 1-install_deps.bat
after upgrading so PyAudioWPatch is installed in .venv.
网页新增“系统更新”区域。选择完整 ZIP 包后,服务会验证压缩包,后台覆盖 D:\Programs\ExePilot,执行 stop.bat、1-install_deps.bat,最后隐藏运行 4-start.bat。更新日志写入 D:\Programs\ExePilot\update.log。
手机端只有在 Windows UI Automation 确认远程文本框后才显示“打开键盘”按钮,点击非文本区域不会再弹出输入法。
- “系统更新”已合并到“系统状态”卡片。
- “一键更新系统 / 重启电脑 / 刷新”集中在同一标题操作区。
- IP 地址改为无边框信息行,并统一类型标签与地址对齐。
系统更新的 Robocopy 命令增加 /IS /IT /IM:更新包中的程序文件会强制覆盖目标目录中的同名文件,即使 Robocopy 判断其大小和时间戳相同,也不会再作为 Same 文件跳过。仍然保留 .venv、updates、transfers、apps.json 与运行日志的排除规则。更新日志现在保留 Robocopy 汇总,便于核对实际复制数量。
“新增直播地址”输入框现在支持粘贴整段文本。后台会提取其中第一个以 http:// 或 https:// 开头的链接,去掉链接末尾常见的中英文标点,只把链接本身追加到 G:\DouyinLiveRecorder\config\URL_config.ini。未找到 HTTP/HTTPS 链接时不会写入文件。
更新器现在会把每一步写入两个日志:
D:\Programs\ExePilot\update.log:所有更新任务的合并日志。D:\Programs\ExePilot\updates\logs\update-<任务编号>.log:单次更新的完整日志。
同时保留:
updates\runners\update-runner-<任务编号>.ps1:实际执行的 PowerShell 脚本,可检查语法和参数。updates\logs\runner-<任务编号>.stdout.log/.stderr.log:PowerShell 在进入脚本前发生的解析、启动错误。updates\logs\start-<任务编号>.stdout.log/.stderr.log:4-start.bat与 Python 启动输出。
日志包含上传包 SHA256、解压目录、PowerShell 版本和身份、文件覆盖前后 SHA256、Robocopy 输出、三个 BAT 的完整输出与退出码、5201 端口检查、启动进程 PID,以及异常位置和 PowerShell 调用栈。网页“系统状态”区域增加了“查看更新日志”按钮。
根据日志停在 RUNNER_PROCESS_CREATED、PowerShell 没有写入 RUNNER_ENTER 的情况,更新启动器增加了 CMD 引导层和启动握手:
updates\logs\bootstrap-<任务编号>.log:在 PowerShell 启动前由 CMD 写入。updates\logs\runner-<任务编号>.handshake.txt:PowerShell 进入脚本参数块后立即写入。updates\logs\launcher-<任务编号>.stdout.log/.stderr.log:记录 Win32_Process.Create 启动帮助程序的输出。- 所有预期日志文件由 Python 预先创建,便于判断失败发生在哪一层。
更新器不再作为 ExePilot 计划任务进程树中的普通子进程运行,而是通过 Win32_Process.Create 创建独立 CMD 引导进程。这样执行 stop.bat 停止 ExePilot 计划任务时,不会同时把更新器本身终止。
- 配置列表右侧新增“高级设置”,命令行启动与新增/编辑配置默认隐藏。
- 实时屏幕位于配置列表及可选高级设置之后;展开高级设置时自然下移。
- 远程发送文本与远程剪贴板共用一个多行文本框,Ctrl+Enter 可快速发送。
- 新增 Ctrl+S、Ctrl+F、Alt+Tab、Ctrl+Shift+Esc、Ctrl+Alt+Del、Win+D、F5 等常用快捷键。
- 快捷键按钮使用统一网格、统一高度和统一宽度。
- 实时屏幕标题栏新增“断开连接 / 重新连接”按钮。
- 手动断开只关闭当前浏览器的 WebRTC PeerConnection,不停止 FastAPI、计划任务或其他客户端。
- 手动断开后暂停自动重连,以节省受控端上行带宽和客户端流量。
- 点击“重新连接”会先使旧连接及未完成的协商失效、关闭旧 PeerConnection、清除重连定时器,再建立全新连接。
- 连接中再次触发重连也会执行完整的先断开、后连接流程。
断开或重连时,浏览器会调用 POST /api/webrtc/disconnect/{connection_id},只关闭当前浏览器对应的服务端 WebRTC PeerConnection。FastAPI 服务、计划任务、程序启动功能以及其他浏览器客户端均不会停止。这样可立即停止该客户端的视频和音频编码/传输,而不必等待 ICE 超时。
- 页面新增“在线编辑”区域,左侧显示最近打开的远程文件,右侧为多行文本编辑器。
- 顶部支持打开、保存、另存为、重新加载、新建空白。
- 打开和保存都针对运行 ExePilot 的远程 Windows 服务器路径。
- 支持 UTF-8、UTF-8 BOM、UTF-16 BOM、GB18030,单个文件最大 10 MB。
- 保存前校验远程文件修改时间,发现外部改动时会提示重新加载或确认强制覆盖。
- 保存采用同目录临时文件加原子替换,最近文件仅记录在当前浏览器 localStorage,不会删除服务器文件。
