Files
LocalNetMsg/package.json
T
xiaoshuai f158377742 fix(compat): Windows 兼容性修复 + 跨平台兼容分析
终端在 Windows 上起不来 (打包规则漏解包)
- 根因: build.asarUnpack 写的是 "**/node_modules/@lydell/node-pty-*/*", 只匹配一层,
  于是 prebuilds/<plat>/ 下的文件没被解包, 留在 app.asar 里
- Windows 上这些必须是磁盘上的真实文件: conpty.dll (OS loader 加载)、
  OpenConsole.exe (CreateProcess)、以及 node-pty 用 worker_threads.Worker 起的
  conoutSocketWorker.js —— node-pty 本身就写了
  __dirname.replace('node_modules.asar', 'node_modules.asar.unpacked') 来适配
- Linux 上看不出来: 只需要一个 pty.node, Electron 的 asar 层能 dlopen 归档里的 .node
- 修复: 规则递归化为 "**/node_modules/@lydell/node-pty-*/**/*"
- 验证: 重新打包后 pty.node 已落到 app.asar.unpacked, 安装版真实 spawn 成功

Windows 保留设备名 / 尾部点空格导致落盘写错
- 新增 src/main/safe-name.ts 的 safeFileName()
- Win32 把 CON/PRN/AUX/NUL/COM1-9/LPT1-9 (带扩展名也算) 当设备, open() 打开的不是文件;
  还会悄悄吃掉文件名结尾的点和空格, 导致 existsSync 判断和实际落盘对不上
- 两处落盘都接上: file-server.ts 的 targetPath()、drive.ts 的 downloadDriveFile()
  (后者名字来自对端共享目录, 属不可信输入)
- 策略是"最小必要": 非法字符全平台都清, 保留名和尾点空格只在 win32 上改写,
  避免动到 Linux 上合法的文件名

其他
- 终端 cwd: Windows 优先用 USERPROFILE (装了 Git Bash 时 HOME 可能是 POSIX 路径, Win32 下不存在)
- USB 面板空列表提示按平台给, 不再一律说"Linux 用户需要在 dialout 组"

分析文档与自测
- 新增 docs/windows-compat.md: 各原生模块的 N-API 情况、已有 win32 分支的位置、
  已知限制 (ConPTY 需 Win10 1809+、防火墙首次弹窗、USB 需 WinUSB 驱动等)、
  以及一份 Windows 真机验证清单
- 自测新增 S1-S8 组: 保留名改写、尾部点空格、非法字符、跨平台不过度清洗、
  超长截断、默认 shell/cwd、asarUnpack 规则回归护栏、上传落盘 + 路径穿越
- 全部 38 条用例通过
2026-10-20 16:59:26 +08:00

127 lines
4.7 KiB
JSON

{
"name": "local-net-msg",
"version": "0.1.0",
"private": true,
"description": "局域网即时通讯 (Electron + Vue 3) - 飞书风格",
"homepage": "https://github.com/localnetmsg/local-net-msg",
"author": "LocalNetMsg <dev@localnetmsg.local>",
"main": "out/main/index.js",
"scripts": {
"dev": "electron-vite dev",
"build": "electron-vite build",
"preview": "electron-vite preview",
"start": "electron-vite preview",
"typecheck:node": "tsc --noEmit -p tsconfig.node.json",
"typecheck:web": "vue-tsc --noEmit -p src/renderer/tsconfig.json",
"typecheck": "npm run typecheck:node && npm run typecheck:web",
"selftest:build": "esbuild scripts/selftest/main.ts --bundle --platform=node --format=cjs --target=node20 --outfile=scripts/selftest/.out/selftest.cjs --alias:electron=./scripts/selftest/electron-stub.cjs --alias:@lydell/node-pty=./scripts/selftest/pty-shim.cjs --external:better-sqlite3 --external:serialport --external:usb --external:node-hid --external:sudo-prompt --external:ws",
"selftest": "npm run selftest:build && cross-env ELECTRON_RUN_AS_NODE=1 electron scripts/selftest/.out/selftest.cjs",
"package:win": "cross-env ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/ electron-vite build && electron-builder --win --x64",
"package:mac": "cross-env ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/ electron-vite build && electron-builder --mac",
"package:linux": "cross-env ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/ electron-vite build && electron-builder --linux",
"package:dir": "cross-env ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/ electron-vite build && electron-builder --dir",
"postinstall": "electron-builder install-app-deps"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@lydell/node-pty": "^1.2.0-beta.12",
"@xterm/addon-fit": "^0.11.0",
"@xterm/addon-web-links": "^0.12.0",
"@xterm/xterm": "^6.0.0",
"better-sqlite3": "^11.5.0",
"electron-store": "^8.2.0",
"element-plus": "^2.8.4",
"highlight.js": "^11.10.0",
"markdown-it": "^14.3.0",
"node-hid": "^3.3.0",
"pinia": "^2.2.4",
"serialport": "^13.0.0",
"sudo-prompt": "^9.2.1",
"usb": "^3.0.1",
"ws": "^8.18.0"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.11",
"@types/markdown-it": "^14.1.2",
"@types/node": "^22.7.5",
"@types/ws": "^8.5.12",
"@vitejs/plugin-vue": "^5.1.4",
"cross-env": "^7.0.3",
"electron": "^32.1.2",
"electron-builder": "^24.13.3",
"electron-vite": "^2.3.0",
"typescript": "^5.6.2",
"vite": "^5.4.8",
"vue": "^3.5.10",
"vue-router": "^4.4.5",
"vue-tsc": "^2.1.6"
},
"build": {
"appId": "com.localnetmsg.app",
"productName": "LocalNetMsg",
"copyright": "Copyright © 2026",
"directories": {
"output": "dist-Electron",
"buildResources": "resources"
},
"npmRebuild": false,
"files": [
"out/**/*",
"package.json"
],
"asarUnpack": [
"**/node_modules/@lydell/node-pty/**/*",
"**/node_modules/@lydell/node-pty-*/**/*",
"**/node_modules/@node-usb/**/*",
"**/node_modules/usb/prebuilds/**/*",
"**/node_modules/@serialport/**/prebuilds/**/*",
"**/node_modules/node-hid/prebuilds/**/*"
],
"extraResources": [
{
"from": "resources/icon.png",
"to": "icon.png"
}
],
"win": {
"icon": "resources/icon.png",
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
],
"artifactName": "${productName}-${version}-Setup.${ext}"
},
"nsis": {
"oneClick": false,
"perMachine": false,
"allowElevation": true,
"allowToChangeInstallationDirectory": true,
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"shortcutName": "LocalNetMsg"
},
"mac": {
"icon": "resources/icon.png",
"target": "dmg",
"category": "public.app-category.social-networking"
},
"linux": {
"icon": "resources/icons",
"target": [
"deb"
],
"category": "Network",
"synopsis": "LAN instant messaging",
"description": "LocalNetMsg — a LAN instant messaging desktop app.",
"maintainer": "LocalNetMsg <dev@localnetmsg.local>",
"desktop": {
"StartupWMClass": "local-net-msg"
}
}
}
}