From 9de93d2a4d5d883e50380f439cd67c8d3e4663be Mon Sep 17 00:00:00 2001 From: lincube Date: Fri, 24 Apr 2026 08:24:13 +0800 Subject: [PATCH] =?UTF-8?q?fix.hy3=E8=AF=95=E5=9B=BE=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .kilo/package-lock.json | 376 ++++++++++++++++++ .kilo/plans/1776989126427-witty-island.md | 171 ++++++++ .../Services/LauncherFlowCoordinator.cs | 16 +- .../Services/UpdateEngineService.cs | 2 +- 4 files changed, 562 insertions(+), 3 deletions(-) create mode 100644 .kilo/package-lock.json create mode 100644 .kilo/plans/1776989126427-witty-island.md diff --git a/.kilo/package-lock.json b/.kilo/package-lock.json new file mode 100644 index 0000000..ae2321a --- /dev/null +++ b/.kilo/package-lock.json @@ -0,0 +1,376 @@ +{ + "name": ".kilo", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@kilocode/plugin": "7.2.20" + } + }, + "node_modules/@kilocode/plugin": { + "version": "7.2.20", + "resolved": "https://registry.npmjs.org/@kilocode/plugin/-/plugin-7.2.20.tgz", + "integrity": "sha512-M5lMc58Mu9j1zveH+E3ZUKRHefzh+acNAqHGSG3TuF6K2l16KrZlCl38CZlgj2R5Qgaig6Jec/F2p9Rbn3BhCQ==", + "license": "MIT", + "dependencies": { + "@kilocode/sdk": "7.2.20", + "effect": "4.0.0-beta.48", + "zod": "4.1.8" + }, + "peerDependencies": { + "@opentui/core": ">=0.1.99", + "@opentui/solid": ">=0.1.99" + }, + "peerDependenciesMeta": { + "@opentui/core": { + "optional": true + }, + "@opentui/solid": { + "optional": true + } + } + }, + "node_modules/@kilocode/sdk": { + "version": "7.2.20", + "resolved": "https://registry.npmjs.org/@kilocode/sdk/-/sdk-7.2.20.tgz", + "integrity": "sha512-KUpu1fyzcAyZWpiv//834zGLN+PYzIH65crs15VTtUJ9CDvGqcj08EM0XlkF9jMuGQAjHjfRbvCfml3+YO31+Q==", + "license": "MIT", + "dependencies": { + "cross-spawn": "7.0.6" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/effect": { + "version": "4.0.0-beta.48", + "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-beta.48.tgz", + "integrity": "sha512-MMAM/ZabuNdNmgXiin+BAanQXK7qM8mlt7nfXDoJ/Gn9V8i89JlCq+2N0AiWmqFLXjGLA0u3FjiOjSOYQk5uMw==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "fast-check": "^4.6.0", + "find-my-way-ts": "^0.1.6", + "ini": "^6.0.0", + "kubernetes-types": "^1.30.0", + "msgpackr": "^1.11.9", + "multipasta": "^0.2.7", + "toml": "^4.1.1", + "uuid": "^13.0.0", + "yaml": "^2.8.3" + } + }, + "node_modules/fast-check": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.7.0.tgz", + "integrity": "sha512-NsZRtqvSSoCP0HbNjUD+r1JH8zqZalyp6gLY9e7OYs7NK9b6AHOs2baBFeBG7bVNsuoukh89x2Yg3rPsul8ziQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^8.0.0" + }, + "engines": { + "node": ">=12.17.0" + } + }, + "node_modules/find-my-way-ts": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/find-my-way-ts/-/find-my-way-ts-0.1.6.tgz", + "integrity": "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==", + "license": "MIT" + }, + "node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/kubernetes-types": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/kubernetes-types/-/kubernetes-types-1.30.0.tgz", + "integrity": "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q==", + "license": "Apache-2.0" + }, + "node_modules/msgpackr": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.10.tgz", + "integrity": "sha512-iCZNq+HszvF+fC3anCm4nBmWEnbeIAfpDs6IStAEKhQ2YSgkjzVG2FF9XJqwwQh5bH3N9OUTUt4QwVN6MLMLtA==", + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multipasta": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/multipasta/-/multipasta-0.2.7.tgz", + "integrity": "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==", + "license": "MIT" + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pure-rand": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz", + "integrity": "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/toml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/toml/-/toml-4.1.1.tgz", + "integrity": "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/uuid": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", + "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/zod": { + "version": "4.1.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/.kilo/plans/1776989126427-witty-island.md b/.kilo/plans/1776989126427-witty-island.md new file mode 100644 index 0000000..477cdf0 --- /dev/null +++ b/.kilo/plans/1776989126427-witty-island.md @@ -0,0 +1,171 @@ +# LanMountainDesktop 启动器无法启动应用 - 问题分析与修复计划 + +## 1. 项目架构概述 + +LanMountainDesktop 采用**双进程架构**: +- **Launcher** (`LanMountainDesktop.Launcher`) - 启动器,负责版本管理、更新、启动主程序 +- **Host** (`LanMountainDesktop`) - 主应用宿主 + +### 启动流程 +1. 用户启动 `LanMountainDesktop.Launcher.exe` +2. Launcher 扫描 `app-*` 目录,选择最佳版本 +3. 检查并应用待处理的更新 +4. 处理插件升级队列 +5. 启动主程序 `app-{version}/LanMountainDesktop.exe` +6. 通过 IPC 监控主程序启动进度 + +## 2. 问题分析 + +### 2.1 核心问题:主机可执行文件找不到 + +根据代码分析(`DeploymentLocator.cs`),启动器通过以下顺序查找主机可执行文件: + +1. **显式 app-root**(如果通过命令行指定) +2. **已发布部署**(查找 `app-*` 目录) +3. **可移植主机**(直接在应用根目录) +4. **调试主机**(开发模式,查找构建输出路径) +5. **旧版回退路径** + +**当前状态检查**: +- ❌ 未找到 `app-*` 目录(生产部署结构不存在) +- ❌ 未找到 `bin/Debug/**/*.exe`(项目未构建或构建输出不存在) + +### 2.2 可能的启动失败原因 + +| 问题 | 描述 | 优先级 | +|------|------|--------| +| **项目未构建** | LanMountainDesktop 主程序未编译,没有可执行文件 | P0 | +| **部署结构缺失** | 生产模式下缺少 `app-*` 目录结构 | P0 | +| **开发模式路径问题** | 调试模式下路径计算错误或构建输出不在预期位置 | P1 | +| **.NET 版本问题** | 项目使用 .NET 10.0,运行环境可能缺少对应运行时 | P1 | +| **更新应用失败** | `ApplyPendingUpdateAsync` 失败导致无法完成部署 | P2 | +| **IPC 连接超时** | 主程序启动后未及时建立 IPC 连接,导致启动器超时 | P2 | + +### 2.3 关键代码位置 + +- **主机查找逻辑**: `LanMountainDesktop.Launcher/Services/DeploymentLocator.cs` + - `FindCurrentDeploymentDirectory()` - 查找 app-* 目录 + - `ResolveHostExecutable()` - 解析主机路径 + +- **启动协调逻辑**: `LanMountainDesktop.Launcher/Services/LauncherFlowCoordinator.cs` + - `RunAsync()` - 主启动流程 + - `LaunchHostWithIpcAsync()` - 启动主机进程 + +- **更新引擎**: `LanMountainDesktop.Launcher/Services/UpdateEngineService.cs` + - `ApplyPendingUpdateAsync()` - 应用待处理的更新 + +## 3. 诊断步骤 + +### 步骤 1:检查构建状态 +```bash +dotnet --info +dotnet build LanMountainDesktop.slnx -c Debug +``` + +### 步骤 2:验证主机可执行文件是否存在 +检查以下路径是否存在 `LanMountainDesktop.exe`: +- `LanMountainDesktop/bin/Debug/net10.0/` +- `LanMountainDesktop/bin/Release/net10.0/` + +### 步骤 3:测试直接运行主程序(跳过 Launcher) +```bash +dotnet run --project LanMountainDesktop/LanMountainDesktop.csproj +``` + +### 步骤 4:检查 Launcher 启动日志 +在开发模式下运行 Launcher 并查看控制台输出: +```bash +dotnet run --project LanMountainDesktop.Launcher/LanMountainDesktop.Launcher.csproj -- launch +``` + +## 4. 修复计划 + +### 方案 A:构建并配置开发环境(推荐) + +**适用场景**:开发或调试环境 + +1. **构建整个解决方案** + ```bash + dotnet restore + dotnet build LanMountainDesktop.slnx -c Debug + ``` + +2. **验证构建输出** + - 确认 `LanMountainDesktop/bin/Debug/net10.0/LanMountainDesktop.exe` 存在 + - 确认 `LanMountainDesktop.Launcher/bin/Debug/net10.0/LanMountainDesktop.Launcher.exe` 存在 + +3. **测试 Launcher 启动** + ```bash + dotnet run --project LanMountainDesktop.Launcher/LanMountainDesktop.Launcher.csproj -- launch + ``` + +4. **如果路径查找失败,检查 `DeploymentLocator.cs` 中的开发路径** + - 当前逻辑(第 366-375 行)查找: + - `../LanMountainDesktop/bin/Debug/net10.0/LanMountainDesktop.exe` + - `../LanMountainDesktop/bin/Release/net10.0/LanMountainDesktop.exe` + - 确认这些路径与实际的构建输出路径匹配 + +### 方案 B:创建生产部署结构 + +**适用场景**:生产环境或模拟生产环境 + +1. **发布主程序** + ```bash + dotnet publish LanMountainDesktop/LanMountainDesktop.csproj -c Release -o app-1.0.0 + ``` + +2. **创建 .current 标记文件** + ```bash + echo. > app-1.0.0/.current + ``` + +3. **从 Launcher 启动** + - Launcher 应该能找到 `app-1.0.0/LanMountainDesktop.exe` + +### 方案 C:修复潜在的代码问题 + +如果上述方案无法解决问题,可能需要修复代码: + +#### C1. 增强错误处理和日志 +在 `DeploymentLocator.cs` 中添加更详细的日志输出,帮助诊断路径查找失败的原因。 + +#### C2. 检查更新逻辑 +如果 `ApplyPendingUpdateAsync` 失败,可能导致启动中止。检查 `.launcher/update/incoming/` 目录是否有残留的更新文件。 + +#### C3. 调整超时设置 +如果主程序启动较慢,可以适当增加 `LauncherFlowCoordinator.cs` 中的超时时间: +- `StartupSoftTimeout` (当前 10 秒) +- `StartupHardTimeout` (当前 30 秒) + +## 5. 建议执行顺序 + +1. ✅ **首先执行方案 A 的步骤 1-2**(构建项目) +2. ✅ **执行诊断步骤 3**(测试直接运行主程序) +3. ✅ **执行诊断步骤 4**(查看 Launcher 启动日志) +4. 根据日志输出决定后续操作: + - 如果显示 "host executable was not found" → 检查路径配置 + - 如果显示 "update apply failed" → 清理更新缓存 + - 如果主程序启动后超时 → 检查 IPC 连接或增加超时 + +## 6. 验证方法 + +修复后,通过以下方式验证: + +```bash +# 开发模式启动 +dotnet run --project LanMountainDesktop.Launcher/LanMountainDesktop.Launcher.csproj -- launch + +# 或直接运行 Launcher 可执行文件 +# (需要先构建 Launcher) +``` + +启动后应该看到: +1. Splash 窗口显示 +2. 主程序桌面窗口出现 +3. Launcher 自动退出(或最小化到托盘) + +## 7. 注意事项 + +- 项目使用 .NET 10.0(`global.json` 指定版本 10.0.103) +- 确保开发环境已安装对应的 .NET SDK +- 如果修改了 `DeploymentLocator.cs` 的路径查找逻辑,需要同步更新文档 `docs/DEVELOPMENT.md` diff --git a/LanMountainDesktop.Launcher/Services/LauncherFlowCoordinator.cs b/LanMountainDesktop.Launcher/Services/LauncherFlowCoordinator.cs index 1ed1499..fc49cbd 100644 --- a/LanMountainDesktop.Launcher/Services/LauncherFlowCoordinator.cs +++ b/LanMountainDesktop.Launcher/Services/LauncherFlowCoordinator.cs @@ -270,7 +270,18 @@ internal sealed class LauncherFlowCoordinator var updateResult = await _updateEngine.ApplyPendingUpdateAsync().ConfigureAwait(false); if (!updateResult.Success) { - return WithAdditionalDetails(updateResult, launcherContextDetails); + Logger.Warn($"Update apply failed, will try to launch existing version. Error='{updateResult.Message}'."); + reporter.Report("update", "Update failed, launching existing version..."); + // Clean up corrupted update files to prevent repeated failures + try + { + _updateEngine.CleanupIncomingArtifacts(); + } + catch (Exception ex) + { + Logger.Warn($"Failed to cleanup update artifacts after failed update: {ex.Message}"); + } + // Continue to launch existing version instead of aborting } reporter.Report("plugins", "Applying plugin upgrades..."); @@ -278,7 +289,8 @@ internal sealed class LauncherFlowCoordinator var queueResult = new PluginUpgradeQueueService(_pluginInstallerService).ApplyPendingUpgrades(pluginsDir); if (!queueResult.Success) { - return WithAdditionalDetails(queueResult, launcherContextDetails); + Logger.Warn($"Plugin upgrade failed, continuing startup. Error='{queueResult.Message}'."); + reporter.Report("plugins", "Plugin upgrade failed, continuing..."); } if (oobeDecision.ShouldShowOobe) diff --git a/LanMountainDesktop.Launcher/Services/UpdateEngineService.cs b/LanMountainDesktop.Launcher/Services/UpdateEngineService.cs index 04a86b3..8295942 100644 --- a/LanMountainDesktop.Launcher/Services/UpdateEngineService.cs +++ b/LanMountainDesktop.Launcher/Services/UpdateEngineService.cs @@ -1458,7 +1458,7 @@ internal sealed class UpdateEngineService } } - private void CleanupIncomingArtifacts() + internal void CleanupIncomingArtifacts() { foreach (var path in new[] {