mirror of
https://github.com/ILoveBingLu/CipherTalk.git
synced 2026-05-21 12:04:59 +08:00
85 lines
3.1 KiB
JavaScript
85 lines
3.1 KiB
JavaScript
const { execSync } = require('child_process');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
//配置区
|
||
const PROJECT_ROOT = path.join(__dirname, '..');
|
||
const RELEASE_DIR = path.join(PROJECT_ROOT, 'release');
|
||
const INSTALLER_PRJ_DIR = path.join(PROJECT_ROOT, 'MyCoolInstaller');
|
||
const EMBEDDED_NAME = 'EmbeddedInstaller.exe';
|
||
|
||
function log(msg) { console.log(`\n\x1b[36m[Build-Shell]\x1b[0m ${msg}`); }
|
||
function error(msg) { console.error(`\n\x1b[31m[Error]\x1b[0m ${msg}`); process.exit(1); }
|
||
|
||
try {
|
||
// 0. 读取当前项目版本
|
||
const pkg = require(path.join(PROJECT_ROOT, 'package.json'));
|
||
const currentVersion = pkg.version;
|
||
log(`ℹ️ 当前项目版本: v${currentVersion}`);
|
||
|
||
// 1. 找到对应的 NSIS 安装包
|
||
log('🔍 Step 1: 寻找对应的 NSIS 安装包...');
|
||
if (!fs.existsSync(RELEASE_DIR)) error('Release 目录不存在');
|
||
|
||
// 精准匹配当前版本的安装包
|
||
const targetInstallerName = `CipherTalk-${currentVersion}-Setup.exe`;
|
||
const nsisPath = path.join(RELEASE_DIR, targetInstallerName);
|
||
|
||
if (!fs.existsSync(nsisPath)) {
|
||
error(`未找到对应版本的安装包: ${targetInstallerName}\n请先运行 npm run build 生成该版本的 Electron 安装包。`);
|
||
}
|
||
|
||
log(`✅ 找到安装包: ${targetInstallerName}`);
|
||
|
||
// 不需要正则匹配了,版本就是 currentVersion
|
||
const version = currentVersion;
|
||
|
||
// 2. 复制到 WPF 工程目录准备嵌入
|
||
log('🚚 Step 2: 注入到安装器工程...');
|
||
const targetPayloadPath = path.join(INSTALLER_PRJ_DIR, EMBEDDED_NAME);
|
||
fs.copyFileSync(nsisPath, targetPayloadPath);
|
||
|
||
// 3. 编译 WPF 外壳
|
||
log('🔨 Step 3: 快速编译 WPF 外壳...');
|
||
const csprojPath = path.join(INSTALLER_PRJ_DIR, 'MyCoolInstaller.csproj');
|
||
// 使用 PublishSingleFile 确保成单文件
|
||
const publishCmd = `dotnet publish "${csprojPath}" -c Release -r win-x64 --self-contained false -p:PublishSingleFile=true`;
|
||
|
||
try {
|
||
execSync(publishCmd, { stdio: 'inherit' });
|
||
} catch (e) {
|
||
error('WPF 编译失败');
|
||
}
|
||
|
||
// 4. 将最终产物移回 release 目录
|
||
log('🎁 Step 4: 输出最终产物...');
|
||
const wpfOutput = path.join(INSTALLER_PRJ_DIR, 'bin', 'Release', 'net8.0-windows', 'win-x64', 'publish', 'MyCoolInstaller.exe');
|
||
if (!fs.existsSync(wpfOutput)) error(`WPF 产物未找到: ${wpfOutput}`);
|
||
|
||
// 使用 Shell-Setup 后缀区分全量构建
|
||
const finalName = `CipherTalk-${version}-Shell-Setup.exe`;
|
||
const finalPath = path.join(RELEASE_DIR, finalName);
|
||
|
||
try {
|
||
if (fs.existsSync(finalPath)) {
|
||
fs.unlinkSync(finalPath); // 尝试先删除旧文件
|
||
}
|
||
fs.copyFileSync(wpfOutput, finalPath);
|
||
} catch (e) {
|
||
if (e.code === 'EBUSY' || e.code === 'EPERM') {
|
||
error(`目标文件被占用: ${finalPath}\n请关闭正在运行的安装程序或文件夹,然后重试。`);
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
|
||
// 清理临时文件
|
||
fs.unlinkSync(targetPayloadPath);
|
||
|
||
log(`🎉🎉🎉 外壳构建完成!`);
|
||
log(`📂 最终安装包: ${finalPath}`);
|
||
|
||
} catch (err) {
|
||
error(err.message);
|
||
}
|