没有发布会,没有 Release 公告,甚至没在官网挂下载链接——DeepSeek 的 deepseek-harness 仓库里,多了一个 apps/desktop 目录。
官方对它的描述很克制:
桌面应用是完整 dsh Web 应用外的一层 Electron 壳。Electron RunAsNode 子进程启动共享 profile runner,Electron 立即从
dsh-app://app/加载打包内的 Web 入口。
翻译成人话:dsh 有了官方桌面版,自带运行时,双击就能用,不再需要你自己 npx 起服务再开浏览器。
问题是——它现在只存在于源码里。这篇文章记录我把它从源码一路编译成 .exe 安装包的完整过程,包括所有踩过的坑。
一、先确认一件事:官网到底有没有放安装包?
结论很干脆:没有公开二进制。
我把能找的渠道都试了一遍:
| 渠道 | 结果 |
|---|---|
npm @deepseek-ai/dsh-desktop | "private": true → registry 404,装不到 |
GitHub Releases(dsh-v0.1.6-alpha.2 等) | assets = 0,一个安装包都没挂 |
更新源 harness.deepseek.com | 根路径 404 |
更新源 harness-test.deepseek.com | 401(需要飞书鉴权,是内部测试通道) |
官方 README 自己也说得很直白:签名、公证、更新托管都"需要生产发布环境",而 CDN 与容量决策还停留在 proposed(提案)阶段。
所以所谓"下载官方桌面端",实际含义是:自己 clone 源码编译。
二、别搞混:有两个"DeepSeek 桌面端"
这是我在折腾过程中最有价值的发现,先放前面,能帮你省很多时间。
| 官方 Desktop | 社区第三方 Desktop | |
|---|---|---|
| 包名 | @deepseek-ai/dsh-desktop | dsh-plugin-desktop |
| 版本 | 0.1.6-alpha.2 | 2.0.11 |
| 仓库 | deepseek-ai/deepseek-harness → apps/desktop | anywhere-labs/deepseek-harness-desktop(dshdesktop.cn) |
| 形态 | 独立 Electron 应用,自带 dsh 运行时 | 一个 Cordis 插件,组合进 dsh 的 profile |
| dsh 来源 | 打包进 app.asar/dsh,版本与壳锁定 | npm 依赖 @deepseek-ai/dsh@0.1.5-rc.2 |
| 内置运行时 | 自带 Python + Node + pnpm | 用系统 Node/pnpm |
| 默认端口 | 19387(Web 版是 3080) | 由 profile 配置 |
| 签名 | Windows EV + macOS 公证(发布时) | 未走官方签名流程 |
| 授权关系 | 官方 | README 明确声明:与深度求索无隶属、合作、授权或背书关系 |
| 是否有公开安装包 | ❌ 只有源码 | ✅ 官网/Release 直接下 |
如果你只是想立刻用上桌面版,第三方那个是现成的;如果你想要官方版本、自带运行时、版本锁定的那一套,就得跟我一样自己编。
三、环境准备
| 组件 | 版本要求 | 我的实测环境 | ||
|---|---|---|---|---|
| Node.js | `^22.19.0 \ | \ | >=24` | 22.19.0 |
| pnpm | 仓库声明 packageManager: pnpm@11.7.0 | 11.7.0 | ||
| 构建工具 | VS 2022(node-pty / koffi 等原生模块) | Visual Studio Community 2022 | ||
| Python | 编译原生模块用 | 3.14 |
工作区规模:12,072 个文件、314 个 workspace 包。先把心理预期调好。
四、第一步就卡住:git clone 直接挂死
git clone --depth 1 --branch master https://github.com/deepseek-ai/deepseek-harness.git
结果:目录里只有个空的 .git,git 进程 CPU 占用为 0,十分钟纹丝不动。
判断是 git 的传输通道在这网络下不通。改用 HTTP 归档,并且关键是要加 --http1.1:
curl.exe -L --http1.1 --fail `
-o deepseek-harness-master.zip `
https://codeload.github.com/deepseek-ai/deepseek-harness/zip/refs/heads/master
⚠️ 两个坑:
- 不加
--http1.1会在 10 MB 左右被Connection was reset,反复重试都一样;- codeload 不支持 Range,
curl -C -续传会报HTTP server does not seem to support byte ranges,必须一次拉完(31 MB)。
解压:
tar -xf deepseek-harness-master.zip -C D:\dsh-official
五、装依赖 + 构建
cd D:\dsh-official\deepseek-harness-master
pnpm install # 实测 3 分 47 秒
第一次构建就能跑通一大半,但会连续撞上几个"看起来毫无道理"的错误,下面逐个说。
坑 1:构建脚本要读 git rev-parse HEAD
因为我们是解压的 zip,没有 .git,于是:
Error: Command failed: git rev-parse HEAD
at repositoryCommitHash (scripts/client-build-environment.ts:54:29)
好消息是源码留了公开的覆盖变量:
$env:DSH_CLIENT_COMMIT_HASH = '<上游 40 位 commit sha>'
坑 2:Electron 二进制下载失败
Downloading Electron binary...
TypeError: fetch failed
Electron failed to install correctly.
@electron/get 从 GitHub Releases 拉包,在这网络下必失败。换镜像:
$env:ELECTRON_MIRROR = 'https://npmmirror.com/mirrors/electron/'
node apps/desktop/node_modules/electron/install.js
坑 3:内置运行时(primary runtime)的下载
官方桌面自带 Node 24.21.0 + Python 3.12.14 + 一堆 wheel,锁定在 apps/desktop/scripts/primary-runtime-lock.json。
这里有个很关键的设计:下载缓存直接以 sha256 命名——
const destination = join(cache, sha256) // 缓存文件名就是哈希
命中即跳过下载。所以我可以把拿不到的资源用别的方式下好,按哈希名丢进 apps/desktop/.desktop-build/downloads,构建就会直接复用。
各资源的实际可达性(我的网络下):
| 资源 | 来源 | 结果 |
|---|---|---|
| Node 24.21.0 | nodejs.org | ✅ 直连可用 |
| numpy / pandas | files.pythonhosted.org | ✅ 直连可用 |
| pillow / lxml | files.pythonhosted.org | ❌ 卡死 → 换清华源同路径 |
| Python 3.12.14 | github.com/astral-sh/python-build-standalone | ❌ 直连/部分代理失败 → gh-proxy.com 成功 |
坑 4(最阴的一个):Electron 以 Node 模式启动
构建和启动时反复出现:
electron.exe: bad option: --remote-debugging-port=9222
electron.exe exited with 9
退出码 9 是 Node 的参数解析错误——说明 Electron 根本没进 GUI 模式,而是跑成了 Node。
追下去发现根因在我这台机器:我是在 第三方 DSH Desktop 里跑的命令,而桌面版在 PATH 里放了一个 pnpm.cmd shim,内容是:
set "ELECTRON_RUN_AS_NODE=1"
set "npm_config_runtime=electron"
"C:\Program Files\DSH Desktop\DSH Desktop.exe" "…\pnpm\bin\pnpm.mjs" %*
也就是说:这台机器上 pnpm 是在 Electron 里跑的,ELECTRON_RUN_AS_NODE=1 被一路继承给了真正要启动 GUI 的 Electron。
验证一下:
pnpm exec tsx -e "console.log(process.execPath, process.env.ELECTRON_RUN_AS_NODE)"
# C:\Program Files\DSH Desktop\DSH Desktop.exe 1
两个修法,建议都做:
- 把真实 Node 放到 PATH 最前面(治本,顺带解决构建被
STATUS_CONTROL_C_EXIT打断的问题):
$env:PATH = "C:\nvm4w\nodejs;" + $env:PATH
- 给
apps/desktop/scripts/dev.ts打一行本地补丁,启动 GUI 前清掉这个变量:
delete environment.ELECTRON_RUN_AS_NODE
坑 5:prepare-dsh 硬编码了 npmjs 源
流水线跑到 prepare-dsh 时报:
Error: desktop runtime: missing required LibreOffice engine win32-x64
往上翻日志,真正的错误是:
GET https://registry.npmjs.org/@deepseek-ai/libreoffice-kit-win32-x64/-/…tgz error (23)
prepare-dsh.ts 里写死了 https://registry.npmjs.org/(两处:--config.registry 和 NPM_CONFIG_REGISTRY),完全无视你 ~/.npmrc 里的镜像配置。而这个 Office 转换引擎足足有 111 MB,在本网络下从 npmjs 拉必然失败。
改成本地镜像即可(实测 npmmirror 上 HTTP 200、速度飞快):
- '--config.registry=https://registry.npmjs.org/',
+ '--config.registry=https://registry.npmmirror.com/',
...
- NPM_CONFIG_REGISTRY: 'https://registry.npmjs.org/',
+ NPM_CONFIG_REGISTRY: 'https://registry.npmmirror.com/',
改完立刻通过:
Office runtime versions and document round trips passed.
坑 6:electron-builder 拉 NSIS 时超时
⨯ connect ETIMEDOUT 20.205.243.166:443 failedTask=build
20.205.243.166 是 GitHub 的 IP——electron-builder 在从 GitHub Releases 拉 nsis-resources。同样有镜像:
$env:ELECTRON_BUILDER_BINARIES_MIRROR = 'https://npmmirror.com/mirrors/electron-builder-binaries/'
六、一句"顺便说"的自我检讨
中途为了清一个被中断的构建目录,我用了:
cmd /c rmdir /s /q .desktop-build\development
这个目录里有大量指向 workspace 各包的 junction(目录联接)。 rmdir /s 会跟进 junction 去删目标目录的内容,结果一次性清空了 99 个 packages/** 源目录、约 2750 个文件。
恢复方式:用同一个 zip 重新解压覆盖(源码 100% 可还原),再删掉 node_modules 里的软链重新 pnpm install。
教训:清理这类由工具创建的目录,要么交给工具自己的清理逻辑(官方用的是
lstatSync+unlinkSync,不跟进链接),要么用同样"只删链接、不进目标"的脚本。永远不要对含 junction 的目录用rmdir /s或资源管理器直接删。
七、打包成 .exe 安装包
官方给的是未签名打包命令(本机没有 EV 证书,签名版走不通):
$env:PATH = "C:\nvm4w\nodejs;" + $env:PATH
$env:DSH_CLIENT_COMMIT_HASH = '<上游 40 位 commit sha>'
$env:ELECTRON_MIRROR = 'https://npmmirror.com/mirrors/electron/'
$env:ELECTRON_BUILDER_BINARIES_MIRROR = 'https://npmmirror.com/mirrors/electron-builder-binaries/'
$env:PYTHON = 'C:\Python314\python.exe'
cd D:\dsh-official\deepseek-harness-master
pnpm run package:desktop:win:x64:unsigned
打包前需要写 apps/desktop/.env.windows(打包字段只从这个文件读,不回退到 shell 环境变量):
DSH_DESKTOP_APP_ID=com.deepseek.harness
DSH_DESKTOP_AUTO_UPDATE_ENV=test
DSH_DESKTOP_MANDATORY_UPDATE_TEST_ORIGIN=https://harness-test.deepseek.com
DSH_DESKTOP_MANDATORY_UPDATE_PROD_ORIGIN=https://harness.deepseek.com
如果构建阶段已经成功过,只是想把 NSIS 安装器补出来,可以跳过构建直接调 electron-builder(快很多),但要注意:官方流水线由 package-target.ts 负责把 .env.windows 载入环境,直接调用 electron-builder 不会自动加载,必须自己导出上面那几个字段:
cd apps\desktop
$env:DSH_DESKTOP_UNSIGNED='1'
$env:DSH_DESKTOP_APP_ID='com.deepseek.harness'
$env:DSH_DESKTOP_AUTO_UPDATE_ENV='test'
$env:DSH_DESKTOP_MANDATORY_UPDATE_TEST_ORIGIN='https://harness-test.deepseek.com'
$env:DSH_DESKTOP_MANDATORY_UPDATE_PROD_ORIGIN='https://harness.deepseek.com'
$env:ELECTRON_BUILDER_BINARIES_MIRROR='https://npmmirror.com/mirrors/electron-builder-binaries/'
pnpm exec electron-builder --config electron-builder.config.mjs --win --x64 --publish never
八、成果
apps\desktop\.desktop-build\targets\win-x64\unsigned-artifacts\
├── deepseek-harness-0.1.6-alpha.2-win-x64.exe 282.8 MB ← NSIS 安装器
├── deepseek-harness-0.1.6-alpha.2-win-x64.exe.blockmap
└── win-unpacked\ 1.12 GB ← 免安装可运行目录
└── DeepSeek Harness.exe 233 MB
几个实测数据:
- 产品名 DeepSeek Harness,版本
0.1.6-alpha.2(与内置 dsh 完全同版本,这是官方刻意的设计) - 安装器 SHA256:
8761DC25DC9B3AC00A382B02A40AD62D3FFE4CF4528108AA79C498863CA4B34F - 免安装目录 1.12 GB:因为它真的把 Python + Node + pnpm + LibreOffice 引擎全打进去了
- 安装器 282.8 MB(7z 高压缩)
NSIS 配置是 oneClick=false(向导式)+ perMachine=false——仅当前用户安装,不需要管理员权限,装完自动创建开始菜单与桌面快捷方式。
九、安装与第一次启动
- 双击
deepseek-harness-0.1.6-alpha.2-win-x64.exe - 会弹 SmartScreen「Windows 已保护你的电脑」——因为未签名(
CompanyName为空)。点「更多信息」→「仍要运行」 - 走完向导,桌面出现 DeepSeek Harness 快捷方式
启动后:
- Host 监听
19387(注意不是 Web 版的 3080) - 数据目录独占
<DSH_HOME>\profiles\desktop - 自带
load_workspace_dependencies工具,首次调用会把内置 Python 运行时离线装到$DSH_HOME/dsh-runtimes/dsh-primary-runtime - 内置
office-docx / office-pptx / office-xlsx技能
十、插曲:为什么开发态跑起来"连 DeepSeek 的 logo 都没有"?
我先用 dev:desktop 跑开发态截图,发现界面没有 DeepSeek 标识,窗口图标还是 Electron 默认的那个。一度以为是打包坏了,查完才明白:
开发态 dev:desktop | 打包 package:desktop:* | |
|---|---|---|
| client 构建 profile | 默认 profile | --profile official |
| 品牌 | 无官方 logo,标题是通用名 | DSH_CLIENT_TITLE=DeepSeek Harness,启用 packages/client/ui-brand-official |
| 应用图标 | Electron 默认图标 | 随包的 PNG/ICO |
也就是说:官方标识只在打包产物里注入,开发态没 logo 是预期行为。源码里那句 build:official 才是关键:
"build:official": "tsx scripts/build.ts --profile official"
所以想要带 DeepSeek logo 的版本,就必须走打包这条路。
十一、⚠️ 并用的重大提醒:两者会抢同一个 profile
如果你机器上已经装了社区第三方桌面版,想两个一起对比着用,务必注意:
官方 Desktop 在访问任何 profile 之前,会取 Electron 进程级单实例锁,并独占 <DSH_HOME>\profiles\desktop:
// apps/desktop/src/paths.ts
export function resolveDesktopPaths(dshHome: string = resolveDshHome()): DesktopPaths {
return {
profile: join(dshHome, 'profiles', 'desktop'),
lock: join(dshHome, 'profiles', 'desktop', 'lock'),
}
}
而第三方版用的也是同一个 ~/.dsh/profiles/desktop。
结论:
- 开发态
dev:desktop默认写apps/desktop/.desktop-build/development/home(天然隔离),但如果你的环境里已经存在DSH_HOME,它会改用那个共享 home——必须显式指定:
$env:DSH_HOME = 'D:\dsh-official\dsh-home-official'
- 官方打包版会直接用
~/.dsh/profiles/desktop,与第三方版冲突(会话、设置、凭据、插件状态互相干扰),并且官方启动时会清理 profile 内的核心包副本与依赖声明。不要在同一DSH_HOME下同时跑两个。
写这段的时候我只是"提醒一下"。装完之后它立刻应验了,而且真相比这条提醒复杂得多——见下一章。
十二、"装好了,却打不开":一次反直觉的排查
安装很顺利,桌面快捷方式也出来了。双击——转了半天,界面糊着一层,怎么点都没反应。
这一章记录排查过程,因为结论和直觉完全相反。
第一层:Host 根本没起来
先看最硬的指标——官方 Host 应该监听 19387:
Get-NetTCPConnection -LocalPort 19387 -State Listen
# 空。只有 TimeWait —— Host 从未就绪
再对照 profile 目录:
~/.dsh/profiles/desktop/cordis.yml LastWriteTime = 刚刚(= 启动时刻)
也就是说,官方版确实"动"了这个目录 —— 而它是社区第三方版的 profile。
上一章刚提醒过的事,当场应验。
处理:给官方版一个独立的 DSH_HOME。用 .cmd 启动器只在进程内设置:
@echo off
set "DSH_HOME=D:\dsh-official\dsh-home-official"
start "" "%LOCALAPPDATA%\Programs\DeepSeek Harness\DeepSeek Harness.exe"
⚠️ 千万不要用
setx DSH_HOME ...设成用户级环境变量。那会连带改掉第三方版的 home, 正在用的会话/设置/凭据会"看起来全部消失"。
再启动:19387 起来了,官方品牌也渲染出来了(鲸鱼 logo + BETA + "探索未至之境")。
到这一步,任何人都会觉得"修好了"。
但是……界面还是糊的
品牌有了、Host 有了,可整个界面依旧蒙着一层,依旧点不动。
这时候最容易犯的错,是继续猜"是不是还有隐藏的 modal 没关掉"。我决定不猜了,直接连上 DevTools 协议读 DOM。
打包版同样接受 Chromium 参数:
Start-Process "…\DeepSeek Harness.exe" -ArgumentList '--remote-debugging-port=9222'
http://127.0.0.1:9222/json 一列出目标,就看见不对劲的地方:
page dsh-app://shell/update-dialog.html ← 多出来的一个窗口
page DeepSeek Harness / dsh-app://app/ ← 主窗口
居然有第二个窗口。 再探测主窗口的 DOM:
{
"clickAtCenter": "DIV.B8WAgW_card B8WAgW_cardWorkspaceTrigger", // 点击没被遮挡!
"fullScreenFixed": [],
"blurOverlays": ["BODY. filter=blur(2px)"], // 整页被糊了 2px
"renderer console": 0 条错误
}
两个反直觉的结论:
- 点击并没有被任何东西挡住 —— 顶层元素就是正常的业务卡片。用户感觉"点不动",其实是因为画面糊了,误判成卡死。
document.body被加了filter: blur(2px),而且没人移除它。
再去探测那个多出来的窗口:
{ "title": "", "bodyChildren": [] }
完全空白。 一个空白且不肯关闭的窗口,就是它把主窗口一直按在"模糊"状态。
真凶:update-overlay.ts
翻源码,模糊来自 apps/desktop/src/update-overlay.ts:
const unblur = (): void => {
if (blur === undefined || parent.isDestroyed()) return
void parent.webContents.removeInsertedCSS(blur).catch(...)
blur = undefined
}
void parent.webContents.insertCSS('body { filter: blur(2px) !important; }').then((key) => {
blur = key
if (closed) unblur()
})
window.once('closed', () => { closed = true; unblur() }) // ← 唯一的解除路径
这是更新弹窗的模态遮罩:弹窗打开时把主窗口糊掉,突出弹窗。
设计意图没问题,但它只在弹窗 closed 时解除,对"弹窗打开后渲染失败 / 空白"没有任何兜底。于是:
弹窗空白 + 不关闭 = 主窗口永久模糊。
更糟的是,那是个独立窗口:用户既看不到它,也关不掉它,没有任何自救手段。
那这个弹窗为什么会弹?
继续追:为什么一个本地未签名构建,会去弹更新/登录窗?
答案在我自己的打包参数里:
DSH_DESKTOP_AUTO_UPDATE_ENV=test
DSH_DESKTOP_MANDATORY_UPDATE_TEST_ORIGIN=https://harness-test.deepseek.com
这是官方的测试更新通道,走飞书鉴权。实测两个源站:
| 源站 | 响应 | 后果 |
|---|---|---|
harness-test.deepseek.com(我打包时选的) | 401 未经授权 | 触发登录/更新弹窗 → 空白 → 主窗糊死 |
harness.deepseek.com(正式源,anonymous) | 404 | 无需登录,不弹窗 |
按官方文档,测试环境鉴权失败时,打包应用首次启动检查就会提供登录入口并开出沙箱窗口。 这套流程在我们的构建里渲染成了空白窗口,于是把主窗口糊住了。
另外,我一开始还误以为"未签名打包省略自动更新配置 ⇒ 不会检查更新"。 实际上:未签名只是省略了自动更新配置,强制更新策略仍会被配置并轮询。
修复:换成正式 anonymous 通道重新打包。
$env:DSH_DESKTOP_AUTO_UPDATE_ENV='production'
pnpm exec electron-builder --config electron-builder.config.mjs --win --x64 --publish never
验证
| 检查项 | 旧包(test 源) | 新包(production 源) |
|---|---|---|
app.asar 里烧进的源站 | harness-test.deepseek.com | harness.deepseek.com |
| 启动后的窗口列表 | app + update-dialog | 只有 app |
主窗口 body 的 filter | blur(2px) | none |
| Host 19387 | 监听 | 监听 |
干净了。

打包后的官方桌面端:自带运行时,双击即用,不用再自己起服务。
为什么这次排查值得写下来
这个 bug 有意思的地方是:它有两层,而第一层的"成功"会把你引向错误方向。
- 第一层(Home 冲突)是真的,修完 Host 确实起来了 —— 于是你很容易就此收工;
- 但真正的症状(界面糊 + 点不动)来自完全不相干的第二层(更新弹窗遮罩);
- 而第二层的表象("点不动")也是错觉 —— 点击从没被拦住,只是画面糊了。
真正把我拉出泥潭的是两件事,而不是"再猜一下":
- 找一个能证伪的硬指标(端口 19387 到底有没有监听),把"Host 没起来"和"UI 出问题"彻底分开;
- 直接读 DOM,而不是猜 DOM —— 一个
elementFromPoint就能区分"被遮挡"和"只是糊了"。
附:调试打包版的两个技巧
打包版也能吃 Chromium 参数,加 --remote-debugging-port=9222 即可:
http://127.0.0.1:9222/json:列出全部窗口 —— "看不见的第二个窗口"就是这么抓到的document.elementFromPoint(w/2, h/2):判断点击到底被谁接走- 扫
getComputedStyle(el).filter / backdropFilter:找残留的模糊层 - 卡死时的一行急救:关掉那个空白窗口,
unblur立刻执行
// 在 dsh-app://shell/update-dialog.html 目标上执行
window.close()
十三、踩坑总表(可收藏)
| # | 现象 | 根因 | 解法 |
|---|---|---|---|
| 1 | git clone 卡死,CPU 为 0 | git 通道不通 | 改用 codeload 归档 + curl --http1.1 |
| 2 | 下载到 ~10 MB 被 reset | HTTP/2 不稳 | 加 --http1.1(且不支持续传) |
| 3 | Command failed: git rev-parse HEAD | zip 无 .git | 设 DSH_CLIENT_COMMIT_HASH |
| 4 | Electron failed to install correctly | GitHub 拉 Electron 失败 | ELECTRON_MIRROR 指 npmmirror |
| 5 | Python/pillow/lxml 下载卡住 | GitHub / pythonhosted 不通 | 预置 sha256 命名的缓存;用 gh-proxy / 清华源 |
| 6 | electron.exe: bad option: --remote-debugging-port | 宿主 pnpm.cmd shim 注入 ELECTRON_RUN_AS_NODE=1 | PATH 前置真实 Node + dev.ts 清变量 |
| 7 | 构建被 STATUS_CONTROL_C_EXIT 打断 | 同上(Electron 跑 pnpm) | 同上,PATH 前置真实 Node 后彻底解决 |
| 8 | missing required LibreOffice engine | prepare-dsh.ts 硬编码 npmjs,111 MB 拉不动 | 改成 npmmirror(2 处) |
| 9 | connect ETIMEDOUT 20.205.243.166 | electron-builder 从 GitHub 拉 NSIS | ELECTRON_BUILDER_BINARIES_MIRROR |
| 10 | 清理目录后源码消失 | rmdir /s 跟进 junction | 用 zip 重解压恢复;改用不跟进链接的删除方式 |
| 11 | 装完打不开:转半天、界面糊、点不动 | 官方版与第三方版共用 ~/.dsh/profiles/desktop,官方 Host 起不来(19387 无监听) | 给官方版独立 DSH_HOME(启动器进程内设置,别用 setx) |
| 12 | Host 起来了,界面依旧糊且"点不动" | 测试源 401 触发更新/登录弹窗;update-overlay.ts 只在弹窗关闭时 unblur,而该弹窗空白且不关闭 → 主窗永久 blur(2px) | 打包改用 DSH_DESKTOP_AUTO_UPDATE_ENV=production;应急可 CDP 执行 window.close() |
| 13 | "点不动"的错觉 | 其实点击没被遮挡,是整页 filter: blur(2px) 让人误判卡死 | 用 document.elementFromPoint() 区分"被遮挡"与"只是糊了" |
| 14 | EPIPE: broken pipe, write 崩溃弹窗 | 用管道重定向 GUI 应用的 stdout,读取端(脚本)退出后主进程写日志即断管 | 诊断时用 Start-Process(不接管道),不要 *> file 跑 GUI |
十四、小结
- DeepSeek 确实在
deepseek-harness仓库里放了官方桌面端,形态是一个自带运行时的独立 Electron 应用,与内置dsh版本严格锁定。 - 但它目前只有源码:npm 是 private、Release 没有 assets、更新源要么 404 要么要鉴权。想用就得自己编。
- 整套流程在 Windows 上是可复现的,编译期障碍几乎全在网络上(GitHub 与 npmjs 的可达性),而不是代码本身。
- 编译产物质量不错:1.12 GB 的免安装目录、282.8 MB 的安装器、自带 Python/Node/pnpm,Office 文档能力开箱可用。
- 真正的坑在运行期,不在编译期:一是它要独占 profile(与第三方版冲突),二是打包时选的更新源会直接决定应用能不能用。
- 作为预发布版本,这套壳确实还有粗糙的地方 ——
update-overlay.ts对"弹窗渲染失败"零兜底,一旦踩到就是界面永久模糊、且用户无自救手段,这个缺陷值得上游修一修。
最省事的复现路径:编译期和运行期都要照顾到。
编译期:把"踩坑总表"里的 4 个环境变量(DSH_CLIENT_COMMIT_HASH / ELECTRON_MIRROR / ELECTRON_BUILDER_BINARIES_MIRROR / PYTHON)加上 PATH 前置真实 Node,再加上 registry 改 npmmirror 那处补丁。
运行期:务必用 DSH_DESKTOP_AUTO_UPDATE_ENV=production 打包,并给官方版一个独立的 DSH_HOME。这两条做到,才算真正"装完能用"。
本文基于 master 分支(commit ddefc45fbc7f8e46dd73185e68295696d1297887)实测。版本为 0.1.6-alpha.2,属于预发布,接口与行为可能随时变化;签名、公证与更新托管需官方生产发布环境。请以官方仓库为准。