没有发布会,没有 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.com401(需要飞书鉴权,是内部测试通道)

官方 README 自己也说得很直白:签名、公证、更新托管都"需要生产发布环境",而 CDN 与容量决策还停留在 proposed(提案)阶段。

所以所谓"下载官方桌面端",实际含义是:自己 clone 源码编译。


二、别搞混:有两个"DeepSeek 桌面端"

这是我在折腾过程中最有价值的发现,先放前面,能帮你省很多时间。

官方 Desktop社区第三方 Desktop
包名@deepseek-ai/dsh-desktopdsh-plugin-desktop
版本0.1.6-alpha.22.0.11
仓库deepseek-ai/deepseek-harness → apps/desktopanywhere-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.011.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

⚠️ 两个坑:

  1. 不加 --http1.1 会在 10 MB 左右被 Connection was reset,反复重试都一样;
  2. 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.0nodejs.org✅ 直连可用
numpy / pandasfiles.pythonhosted.org✅ 直连可用
pillow / lxmlfiles.pythonhosted.org❌ 卡死 → 换清华源同路径
Python 3.12.14github.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

两个修法,建议都做:

  1. 把真实 Node 放到 PATH 最前面(治本,顺带解决构建被 STATUS_CONTROL_C_EXIT 打断的问题):
$env:PATH = "C:\nvm4w\nodejs;" + $env:PATH
  1. 给 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——仅当前用户安装,不需要管理员权限,装完自动创建开始菜单与桌面快捷方式。


九、安装与第一次启动

  1. 双击 deepseek-harness-0.1.6-alpha.2-win-x64.exe
  2. 会弹 SmartScreen「Windows 已保护你的电脑」——因为未签名(CompanyName 为空)。点「更多信息」→「仍要运行」
  3. 走完向导,桌面出现 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 条错误
}

两个反直觉的结论:

  1. 点击并没有被任何东西挡住 —— 顶层元素就是正常的业务卡片。用户感觉"点不动",其实是因为画面糊了,误判成卡死。
  2. 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.comharness.deepseek.com
启动后的窗口列表app + update-dialog只有 app
主窗口 body 的 filterblur(2px)none
Host 19387监听监听

干净了。

DeepSeek Harness 桌面端主界面

打包后的官方桌面端:自带运行时,双击即用,不用再自己起服务。

为什么这次排查值得写下来

这个 bug 有意思的地方是:它有两层,而第一层的"成功"会把你引向错误方向。

  • 第一层(Home 冲突)是真的,修完 Host 确实起来了 —— 于是你很容易就此收工;
  • 但真正的症状(界面糊 + 点不动)来自完全不相干的第二层(更新弹窗遮罩);
  • 而第二层的表象("点不动")也是错觉 —— 点击从没被拦住,只是画面糊了。

真正把我拉出泥潭的是两件事,而不是"再猜一下":

  1. 找一个能证伪的硬指标(端口 19387 到底有没有监听),把"Host 没起来"和"UI 出问题"彻底分开;
  2. 直接读 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()

十三、踩坑总表(可收藏)

#现象根因解法
1git clone 卡死,CPU 为 0git 通道不通改用 codeload 归档 + curl --http1.1
2下载到 ~10 MB 被 resetHTTP/2 不稳加 --http1.1(且不支持续传)
3Command failed: git rev-parse HEADzip 无 .git设 DSH_CLIENT_COMMIT_HASH
4Electron failed to install correctlyGitHub 拉 Electron 失败ELECTRON_MIRROR 指 npmmirror
5Python/pillow/lxml 下载卡住GitHub / pythonhosted 不通预置 sha256 命名的缓存;用 gh-proxy / 清华源
6electron.exe: bad option: --remote-debugging-port宿主 pnpm.cmd shim 注入 ELECTRON_RUN_AS_NODE=1PATH 前置真实 Node + dev.ts 清变量
7构建被 STATUS_CONTROL_C_EXIT 打断同上(Electron 跑 pnpm)同上,PATH 前置真实 Node 后彻底解决
8missing required LibreOffice engineprepare-dsh.ts 硬编码 npmjs,111 MB 拉不动改成 npmmirror(2 处)
9connect ETIMEDOUT 20.205.243.166electron-builder 从 GitHub 拉 NSISELECTRON_BUILDER_BINARIES_MIRROR
10清理目录后源码消失rmdir /s 跟进 junction用 zip 重解压恢复;改用不跟进链接的删除方式
11装完打不开:转半天、界面糊、点不动官方版与第三方版共用 ~/.dsh/profiles/desktop,官方 Host 起不来(19387 无监听)给官方版独立 DSH_HOME(启动器进程内设置,别用 setx)
12Host 起来了,界面依旧糊且"点不动"测试源 401 触发更新/登录弹窗;update-overlay.ts 只在弹窗关闭时 unblur,而该弹窗空白且不关闭 → 主窗永久 blur(2px)打包改用 DSH_DESKTOP_AUTO_UPDATE_ENV=production;应急可 CDP 执行 window.close()
13"点不动"的错觉其实点击没被遮挡,是整页 filter: blur(2px) 让人误判卡死用 document.elementFromPoint() 区分"被遮挡"与"只是糊了"
14EPIPE: 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,属于预发布,接口与行为可能随时变化;签名、公证与更新托管需官方生产发布环境。请以官方仓库为准。