开源 DeskPeek:把手机变成自己电脑的小监视器
一个 Windows 单文件小工具手机浏览器直接看自己电脑的屏幕直播需要时还能点一下。手机上不装 App、没有账号、不要配对码。一、为什么要做这个场景很具体电脑上正跑着一个十几分钟才出结果的活——AI 编程 agent 在改代码、dotnet build在编、几十 GB 的东西在下载、某个脚本在等回调。人已经从书桌挪到沙发上了但手边只有手机而你就是想瞄一眼到哪一步了是不是卡住了要不要点那个继续。我先把现成方案都试了一圈没有一个合这个尺度的需求方案为什么没选RustDesk / ToDesk / TeamViewer两端都要装要账号或配对码。我只要看一眼 点一下用不上完整桌面串流Windows 远程桌面家庭版根本不带 RDP 服务端就算带手机上是按键盘鼠标设计的交互触摸很难受VNC同样要装服务端手机还得装 Viewer定时截图刷新网页能看不能点延迟难看于是写了DeskPeek电脑上跑一个小 exe手机浏览器打开一个网址就完事。现在用得最多的功能就是第一条场景——躺着盯 AI agent 在电脑上干活需要点接受 / 继续 / 运行的时候从手机上点一下。二、它能做什么不能做什么能看整块虚拟屏幕含多显示器实时直播帧率 1–30fps默认 10、JPEG 质量 10–100默认 60、可缩到 1280 宽省流量默认开点手机点一下 电脑左键单击一次。要显式开启且必须设访问口令稳断流自动重连直播期间阻止系统睡眠防火墙规则跟着端口走走可以顺手把服务通过 frp 转到公网自备 frpc软件负责写配置和拉起不能说在前面比让用户自己撞到好只有左键单击。没有键盘、拖拽、右键、滚轮锁屏界面和 UAC 提权弹窗点不了—— Windows 不允许向安全桌面注入输入这是系统级限制不是 bug没有声音、没有多路画面、没有文件传输只跑在 Windows 上抓屏用的 GDI手机端不需要装任何东西三、技术选型为什么是 MJPEG整个链路一句话就能说完GDI 抓屏 → GDI 压 JPEG → multipart/x-mixed-replace 一路吐 → 手机 img 直接播MJPEG 最被低估的点是img src/stream这一行不需要任何 JavaScript、不需要播放器、不需要信令服务器。浏览器原生就认一个持续替换画面的图片响应这是 WebRTC 和 WebSocket 都换不来的省事。被问过要不要上更现代的方案都比一比方案真实代价WebRTC信令服务 ICE/TURN SRTP 编解码协商。为瞄一眼太贵WebSocket canvas要么在 JS 里自己解码 JPEG要么每帧转 blob URL心跳、重连、背压全得自己写——而这些为了 MJPEG 我照样要写截图轮询每帧一次 HTTP 请求延迟和流量都不好看DXGI Desktop Duplication帧率上限更高但要引 D3D11 互操作还要处理输出复制的独占语义。10fps 够用的场景不值得服务端就是.NET Framework 4.7.2 WinForms HttpListener零第三方依赖产物一百多 KB 一个 exe。选 Framework 而不是 .NET 8 的理由非常现实系统自带运行时不用打包 60MB 的 self-contained而 WinForms 设计器拖控件改界面比手写布局代码快一个数量级——这种小工具的界面改动极其频繁。四、真正花时间的地方九个坑功能本身一天就跑起来了剩下的时间全在处理为什么手机上看着不对。这部分才是我觉得值得写出来的。4.1 有时候连不上其实是电脑睡了不是 bug是电源策略。机器进了 S3 之后网络栈就没了手机当然打不开而现象呈现为时好时坏特别像代码问题。现在服务运行期间会调用SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);只拦系统睡眠不碰显示器电源策略ES_DISPLAY_REQUIRED会把屏幕也钉住那是在替你费电。停止服务或退出程序立刻恢复。4.2 MJPEG 断了浏览器不会自己重连这条最坑Wi-Fi 抖一下、电脑睡醒一次、手机切到后台流都会断。而断了之后画面永久停在最后一帧用户看到的结论就是连不上可服务端其实活得好好的。浏览器对multipart/x-mixed-replace没有任何自动恢复机制所以只能自己做每次开流分配一个 generation token回调里比对避免旧流的重试把新流干掉onload后 10 秒内没等到新帧就判定断开帧率下限 1fps10 秒足以区分卡和断按 1s → 2s → 4s → 8s 指数退避重连visibilitychange切后台停止重试回前台立即重开请求 URL 带时间戳。URL 一模一样的话有些浏览器会复用那条已经死掉的连接4.3 防火墙规则不跟端口走Windows 防火墙按程序放行看着够用但只要换端口、或者网卡被归到 Public profile就会出现电脑这边一切正常、手机就是打不开。现在启动时按当前端口重建自己那条入站规则DeskPeek-ScreenLive先删再加避免残留旧端口。而且绝不去动用户自己建的规则。netsh的中文输出没法可靠解析所以只判断退出码失败就在状态行追加一句防火墙放行失败请手动放行 TCP xxxx。不弹窗打断也不静默失败。4.4 DPI 缩放吃掉画面右下角系统 150% 缩放时进程如果不声明 DPI 感知SystemInformation.VirtualScreen拿到的是缩放后的逻辑尺寸抓出来的图右下各缺一块。在app.manifest里声明dpiAwarenessSystem之后拿到的才是物理像素另外用GetDeviceCaps(DESKTOPHORZRES / DESKTOPVERTRES)校验一次。4.5 多显示器负坐标点击落点跑偏副屏在主屏左边时VirtualScreen.X是负数。点击控制一开始传的是像素坐标结果一开缩小到 1280 宽、或者手机横竖屏一换落点就飘。最后改成传 0~1 的画面比例像素留给服务端算int x vs.X (int)Math.Round(fx * (vs.Width - 1)); // vs SystemInformation.VirtualScreen这样缩放开关、系统 DPI、多屏原点全都跟它无关——因为Cursor.Position和VirtualScreen本来就是同一个坐标空间。4.6 iPhone Safari 不支持屏幕旋转得用 CSS 兜底Android Chrome 走requestFullscreen()screen.orientation.lock(landscape)就完事了。iOS Safari 没有 Fullscreen API只能把整个画面容器transform: rotate(90deg)硬画出来。代价是触摸坐标要做轴交换——旋转 90° 之后视口轴和图片轴互换了if (rotated) { x sy / r.height; y 1 - sx / r.width; }else { x sx / r.width; y sy / r.height; }这行公式是拿浏览器自己的 transform matrix 反算验证过的不是猜的。另外 iOS 的100vh不随横屏和工具栏收放变化所以布局一律用window.visualViewport的真实尺寸。4.7 横屏之后回不到竖屏第一版横屏时把顶部工具栏visibility:hidden掉了自作聪明觉得这样沉浸。结果走 CSS 兜底的机器一进横屏就没有任何按钮可点永久回不去只能杀掉页面重来。现在横屏时工具栏变成浮在左上角的半透明小条避开刘海安全区还原和触控随时点得到退出横屏时额外调一次screen.orientation.unlock()因为有些浏览器退出全屏后方向锁定还留着。4.8 微信内置浏览器不弹认证框设了访问口令走的是 HTTP Basic。桌面浏览器会弹登录框但微信这类内置浏览器不允许弹于是它把我们 401 的正文当成网页内容直接显示出来——用户看到的是屏幕上孤零零一行401 需要访问口令然后来问我为什么连不上。解法是老老实实加一个登录页/未登录时返回一个正常 HTML 表单POST 到/login校验通过发一个随机 32 位 hex 的HttpOnly会话 cookie12 小时滑动续期整夜看不会被踢下线之后img的长连接和fetch(/click)都自动带上它Basic 认证同时保留桌面浏览器里存过口令的体验不变不再发WWW-Authenticate挑战否则某些浏览器还是会去弹那个它弹不出来的框页面上还加了兜底断流重连和点击都会探一次/auth-check登录态过期就自动跳回登录页不会卡在连接中断里无限重试。4.9 跨线程读控件症状是明明勾了却没生效HttpListener的请求处理跑在线程池线程上而鉴权逻辑要读允许手机点击控制这个复选框和两个口令输入框。从非 UI 线程读控件属性本身就是非法跨线程访问挂着调试器时会抛异常而异常被请求外层的try/catch吞掉了。现在改成 UI 线程改一处就同步一份快照字段请求线程只读快照行为跟有没有调试器、有没有断点都无关。五、安全上做了什么取舍点击控制等于把这台电脑的操作权交出去所以这里的默认值全都偏保守机制说明三条件缺一不可勾选开关 用户名非空 密码非空。少哪一项403 文案就点名哪一项状态行同步显示不用你猜手机端触控默认关闭按钮变橙色才发包防止口袋误触和页面重试打串限流/click最快 100ms 一次约每秒 10 次超了返回429 点击太快会话管理cookie 随机 32 位 hex、HttpOnly、SameSiteLax改口令或停止服务旧登录态立即作废公网警告开着 frp 转发又开着点击控制时状态行直接写公网那端可以试口令并直接操作这台电脑明文这一点不遮掩全程 HTTP。局域网内够用要过公网就设强口令或者只看不点403 长这样故意写成缺什么而不是复读需求403 点击控制未开启电脑上的访问用户名是空的六、上手三步右键 → 以管理员身份运行。服务绑的是http://:8080/监听所有网卡不是管理员会直接启动失败。点启动服务。状态行会打印手机真正能访问的地址——取的是默认路由那张网卡的 IPv4多网卡时其余地址也会列出来避免给你个 VPN 地址。手机连同一个路由器/Wi-Fi浏览器打开那个地址输口令进画面。登录页是普通的网页表单不是浏览器弹的认证框所以在微信内置浏览器里也能登。想用手机点击的话电脑上勾选允许手机点击控制并把用户名密码都填上手机上再点触控然后点哪儿就在哪儿落一次左键七、源码与构建项目信息详情项目名称DeskPeek开源地址https://gitee.com/known/DeskPeek技术栈.NET Framework 4.7.2 Windows Forms HttpListener零第三方依赖许可证Apache 2.0运行环境Windows手机端任意浏览器含微信内置浏览器MSBuild.exe -t:Rebuild -v:minimal DeskPeek.csproj# 产物bin\Debug\DeskPeek.exe代码量很小三个文件值得看MainForm.cs服务、鉴权、抓屏推流、点击注入、frp 集成、ScreenCapture.csGDI 抓屏与物理分辨率、内嵌的IndexHtml手机端播放与重连、触摸坐标换算。八、接下来可能做的键盘输入 / 右键 / 滚轮点击已经是够用的边界再往上就是远程桌面了DXGI Desktop Duplication 提高帧率上限自签 TLS让公网场景不再是明文手机端 PWA 化加到主屏、独立窗口如果你有其它想法欢迎开 issue 或直接改。写在最后做这个工具的动机小得不好意思说出口我就是想在沙发上瞄一眼电脑上的编译跑到哪了。但正是这种不值一提的需求最容易掉进现有工具的缝里——远程桌面太重截图刷新太笨装 App 太麻烦。工具不需要大能在你需要的时候把信息递到手边就够了。

相关新闻

基于SVM、随机森林与DNN的恶意网站检测系统实战

基于SVM、随机森林与DNN的恶意网站检测系统实战

简介:这是一套面向高校计算机、人工智能与电子信息等专业学生的机器学习实践资源,围绕恶意网站检测这一网络安全场景,提供从特征提取到多算法验证的完整实现方案。压缩包共11个文件,约3.32MB,以Python脚本为主体&#…

2026/10/14 0:38:53 阅读更多 →
基于Python深度学习与Neo4j的装备知识图谱构建与网页应用实战

基于Python深度学习与Neo4j的装备知识图谱构建与网页应用实战

简介:本资源为基于Python深度学习与Neo4j的军事装备知识图谱网页应用完整项目包,面向计算机、人工智能、数据科学等专业的学生与开发者,可用于毕业设计、课程设计或初期项目立项演示。项目由数据爬虫、数据管理、数据处理、知识问答、新闻热点…

2026/10/14 0:38:53 阅读更多 →
检索回来的 5 条,有 4 条其实是同一篇

检索回来的 5 条,有 4 条其实是同一篇

版权与内容来源声明 本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容,均在附表 A 中标注来源;引用官方原文保持原样,不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准,标注「待验证」的部…

2026/10/14 0:38:53 阅读更多 →

最新新闻

Kafka 生产环境分区热点倾斜治理:基于 Key 加盐与动态再均衡的高并发解法

Kafka 生产环境分区热点倾斜治理:基于 Key 加盐与动态再均衡的高并发解法

在每年双 11 的大促峰值期,许多负责消息中间件保障的架构师都会遇到一个极具迷惑性的“假象报警”: 打开 Kafka 全局监控大盘,集群整体的 CPU 利用率仅仅只有 35%,网络入网总带宽距离物理网卡上限还有一半以上的富余,看…

2026/10/14 1:23:07 阅读更多 →
算法岗实习面试全攻略:字节、PayPal、寒武纪等五家大厂面经与避坑指南

算法岗实习面试全攻略:字节、PayPal、寒武纪等五家大厂面经与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 1:23:07 阅读更多 →
单端口与双端口RAM实现指南:Verilog代码、时序与综合推断

单端口与双端口RAM实现指南:Verilog代码、时序与综合推断

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 1:23:07 阅读更多 →
Java 24 作用域值(Scoped Values)实战:彻底淘汰 ThreadLocal 消除内存泄露

Java 24 作用域值(Scoped Values)实战:彻底淘汰 ThreadLocal 消除内存泄露

在 Java 企业级服务端研发领域,ThreadLocal 无疑是陪伴了大家二十余年的“老朋友”。无论是 Spring 的事务管理器、Logback 的 MDC 链路追踪上下文、还是微服务网关透传的当前登录用户信息,几乎全部依托 ThreadLocal 在线程私有存储中穿针引线。 然而&am…

2026/10/14 1:23:07 阅读更多 →
跨机房专线延迟下的数据双写冲突消解:分布式逻辑时钟与 LWW 策略实战

跨机房专线延迟下的数据双写冲突消解:分布式逻辑时钟与 LWW 策略实战

在三地五中心的单元化异地多活架构中,最令架构师头疼的技术挑战,永远是打破了“单一机房封闭”的跨地域共享数据双写。 虽然我们在设计上极力强调“按用户维度做单元封闭(Cell Isolation)”,但在真实的电商与金融生态中…

2026/10/14 1:23:07 阅读更多 →
Unity AssetBundle标签策略:功能模块化vs资源类型化

Unity AssetBundle标签策略:功能模块化vs资源类型化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 1:22:07 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →