Skip to content

Commit

Permalink
Refactor/windows custom install UI (#247)
Browse files Browse the repository at this point in the history
* chore: update nsic script
* chore: migration to nsis 3.x

---------

Co-authored-by: 夜鹰 <17kungfuboy@gmail.com>
Co-authored-by: scarqin <1054139596@qq.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Scarqin <scarqin@gmail.com>
  • Loading branch information
5 people committed Mar 2, 2023
1 parent 1168bc0 commit 976f3ff
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 158 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

# compiled output
dist/
/build/ElectronInstall/
/build/FilesToInstall/
/build/Output/
/build/NiuNiuCaptureElectronDemo/
out/
/tmp
/out-tsc
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "postcat",
"name": "Postcat",
"souceLocale": "zh-Hans",
"version": "0.3.0",
"main": "out/app/electron-main/main.js",
"description": "A lightweight, extensible API tool",
"homepage": "https://github.com/Postcatlab/postcat.git",
"author": "Postcat",
"private": true,
"private": true,
"workspaces": [
"src/workbench/*"
],
Expand All @@ -18,6 +18,7 @@
"build": "npx patch-package && npm-run-all -s electron:build:web clear:electron:tsc electron:tsc && npx esno scripts/build.ts",
"build:web": "yarn workspace postcat-web run build:web",
"build:static": "npm run clear:electron:tsc&&npm run electron:tsc && npx esno scripts/build.ts",
"build:win:noSign": "npm run clear:electron:tsc&&npm run electron:tsc && npx esno scripts/buildNoSign.ts",
"electron:build:web": "yarn workspace postcat-web run build",
"electron:static": "npm run electron:tsc && electron .",
"release": "npm-run-all -s electron:build:web electron:tsc && npx esno scripts/build.ts --publish=always && node upload.js",
Expand All @@ -30,7 +31,7 @@
"web:start:direct": "yarn workspace postcat-web run start:direct",
"version": "conventional-changelog -p angular -i CHANGELOG.md -s -r -0",
"lint:lint-staged": "lint-staged",
"wininstaller": "node scripts/beforeNSISBuild.js && cd build && build-nim.bat",
"wininstaller": "cd build && build-for-electron-postcat.bat",
"pack:win": "npm run electron:build && npm run wininstaller",
"deployWindows": "node scripts/deployWindows.js",
"releaseWindows": "npx esno scripts/releaseWindows.ts"
Expand Down Expand Up @@ -128,4 +129,4 @@
"prettier --write"
]
}
}
}
67 changes: 37 additions & 30 deletions scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { build, BuildResult, Platform } from 'electron-builder';
import type { Configuration } from 'electron-builder';
import minimist from 'minimist';

import pkgInfo from '../package.json';
import { ELETRON_APP_CONFIG } from '../src/environment';

import { execSync, exec, spawn } from 'node:child_process';
import { copyFileSync, readFileSync, writeFileSync } from 'node:fs';
import path, { resolve } from 'node:path';
import { exit, platform } from 'node:process';

const pkgPath = path.join(__dirname, '../package.json');
// 当前 postcat 版本
const version = process.env.npm_package_version;
// 保存签名时的参数,供签名后面生成的 自定义安装界面 安装包
Expand Down Expand Up @@ -61,6 +63,8 @@ const config: Configuration = {
],
generateUpdatesFilesForAllChannels: true,
nsis: {
// 指定guid,此guid会存放在注册表中,如果没有指定则系统会自动生成
guid: 'Postcat',
oneClick: false,
allowElevation: true,
allowToChangeInstallationDirectory: true,
Expand Down Expand Up @@ -114,22 +118,22 @@ const config: Configuration = {
icon: 'src/app/common/images/',
target: ['AppImage']
}
// https://www.electron.build/configuration/configuration.html#afterallartifactbuild
// afterAllArtifactBuild: async (buildResult: BuildResult) => {
// console.log('buildResult.artifactPaths', buildResult.artifactPaths);
// if (isWin) {
// await signWindows();
// // https://github.com/electron-userland/electron-builder/issues/4446
// const latestPath = path.join(__dirname, '../release/latest.yml');
// const file = readFileSync(latestPath, 'utf8');
// // @ts-ignore
// writeFileSync(latestPath, file.replaceAll(`Postcat-Setup-${version}.exe`, `Postcat Setup ${version}.exe`));
// return buildResult.artifactPaths.map(filePath => {
// return filePath.replace(`Postcat Setup ${version}.exe`, `Postcat-Setup-${version}.exe`);
// });
// }
// return buildResult.artifactPaths;
// }
};

// 这里动态往 package.json 中写入 electron-builder 配置,主要是为了给 build-for-electron.bat 脚本读取配置
const modifyPkgInfo = () => {
// @ts-ignore
pkgInfo.build = config;
writeFileSync(pkgPath, JSON.stringify(pkgInfo, null, 2));
// 退出进程/意外退出进程 时主动还原 package.json 信息
process.on('exit', restorePkgInfo);
process.on('uncaughtException', restorePkgInfo);
};

const restorePkgInfo = () => {
Reflect.deleteProperty(pkgInfo, 'build');
// 还原 package.json 文件
writeFileSync(pkgPath, JSON.stringify(pkgInfo, null, 2));
};

// 要打包的目标平台
Expand All @@ -147,26 +151,29 @@ const signWindows = () => {
return resolve(true);
}

// 给卸载程序签名
signOptions[0] = {
...signOptions[0],
path: 'D:\\git\\postcat\\build\\Uninstall Postcat.exe'
};
await sign(...signOptions);

copyFileSync(
path.join(__dirname, '../build', 'Uninstall Postcat.exe'),
path.join(__dirname, '../release/win-unpacked', 'Uninstall Postcat.exe')
);

modifyPkgInfo();
// 生成自定义安装包
const ls = spawn('yarn', ['wininstaller'], {
// 仅在当前运行环境为 Windows 时,才使用 shell
shell: isWin
});

ls.stdout.on('data', async data => {
console.log(decoder.decode(data));
if (decoder.decode(data).includes('请按任意键继续')) {
const logText = decoder.decode(data);
console.log(logText);

// build/nsis-build-and-sign.bat
if (logText.includes('是时候给 Uninstall Postcat.exe 签名了')) {
signOptions[0] = {
...signOptions[0],
path: 'D:\\git\\postcat\\release\\Uninstall Postcat.exe'
};
await sign(...signOptions);
console.log('卸载程序签名完成!');
}

// build/build-by-external.bat
if (logText.includes('pack postcat finished!')) {
// 给自定义安装包签名
signOptions[0] = {
...signOptions[0],
Expand Down
174 changes: 174 additions & 0 deletions scripts/buildNoSign.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { sign, doSign } from 'app-builder-lib/out/codeSign/windowsCodeSign';
import { build, BuildResult, Platform } from 'electron-builder';
import type { Configuration } from 'electron-builder';
import minimist from 'minimist';
import YAML from 'yaml';

import pkgInfo from '../package.json';
import { ELETRON_APP_CONFIG } from '../src/environment';

import { execSync, exec, spawn } from 'node:child_process';
import { createHash } from 'node:crypto';
import { copyFileSync, createReadStream, readFileSync, writeFileSync } from 'node:fs';
import path, { resolve } from 'node:path';
import { exit, platform } from 'node:process';

const pkgPath = path.join(__dirname, '../package.json');
// 当前 postcat 版本
const version = process.env.npm_package_version;
// 保存签名时的参数,供签名后面生成的 自定义安装界面 安装包
let signOptions: Parameters<typeof sign>;

const isWin = process.platform === 'win32';
// 参数同 electron-builder cli 命令行参数
const argv = minimist(process.argv.slice(2));
// https://nodejs.org/docs/latest/api/util.html#util_class_util_textdecoder
const decoder = new TextDecoder('gbk');

// 删除 minimist 解析后默认带的 _ 属性,防止 electron-builder 执行报错
Reflect.deleteProperty(argv, '_');

// mac 系统删除 release 目录
if (process.platform === 'darwin') {
exec(`rm -r ${path.resolve(__dirname, '../release')}`);
}

// window 系统删除 release 目录
if (process.platform === 'win32') {
exec(`rd/s/q ${path.resolve(__dirname, '../release')}`);
}

const config: Configuration = {
appId: '.postcat.io',
productName: 'Postcat',
asar: true,
directories: {
output: 'release/'
},
files: [
'out/app/**/*.js*',
'out/platform/**/*.js*',
'out/environment.js',
'out/shared/**/*.js*',
'src/workbench/browser/dist/**/*',
'out/workbench/browser/src/**/*.js*',
'out/workbench/node/**/*.js*',
'out/app/common/**/*',
'!**/*.ts'
],
publish: [
'github',
{
provider: 'generic',
url: ELETRON_APP_CONFIG.BASE_DOWNLOAD_URL
}
],
generateUpdatesFilesForAllChannels: true,
nsis: {
guid: 'Postcat',
oneClick: false,
allowElevation: true,
allowToChangeInstallationDirectory: true,
// for win - 将协议写入主机的脚本
include: 'scripts/urlProtoco.nsh'
},
protocols: [
// for macOS - 用于在主机注册指定协议
{
name: 'eoapi',
schemes: ['eoapi']
}
],
win: {
icon: 'src/app/common/images/logo.ico',
target: ['nsis', 'portable']
// extraFiles: [
// {
// from: './build/Uninstall Postcat.exe',
// to: '.'
// }
// ]
},
portable: {
splashImage: 'src/app/common/images/postcat.bmp'
},
mac: {
icon: 'src/app/common/images/512x512.png',
hardenedRuntime: true,
category: 'public.app-category.productivity',
gatekeeperAssess: false,
entitlements: 'scripts/entitlements.mac.plist',
entitlementsInherit: 'scripts/entitlements.mac.plist',
// target: ['dmg', 'zip']
target: [
{
target: 'default',
arch: ['x64', 'arm64']
}
]
},
dmg: {
sign: false
},
afterSign: 'scripts/notarize.js',
linux: {
icon: 'src/app/common/images/',
target: ['AppImage']
}
};

// 这里动态往 package.json 中写入 electron-builder 配置,主要是为了给 build-for-electron.bat 脚本读取配置
const modifyPkgInfo = () => {
// @ts-ignore
pkgInfo.build = config;
writeFileSync(pkgPath, JSON.stringify(pkgInfo, null, 2));
// 退出进程/意外退出进程 时主动还原 package.json 信息
process.on('exit', restorePkgInfo);
process.on('uncaughtException', restorePkgInfo);
};

const restorePkgInfo = () => {
Reflect.deleteProperty(pkgInfo, 'build');
// 还原 package.json 文件
writeFileSync(pkgPath, JSON.stringify(pkgInfo, null, 2));
};

// 要打包的目标平台
const targetPlatform: Platform = {
darwin: Platform.MAC,
win32: Platform.WINDOWS,
linux: Platform.LINUX
}[platform];

console.log('打包参数', argv);

Promise.all([
build({
config,
targets: targetPlatform.createTarget(),
...argv
})
])
.then(async () => {
modifyPkgInfo();

const ls = spawn('yarn', ['wininstaller'], {
// 仅在当前运行环境为 Windows 时,才使用 shell
shell: isWin
});

ls.stdout.on('data', async data => {
console.log(decoder.decode(data));
// build-by-external.bat
if (decoder.decode(data).includes('pack postcat finished!')) {
console.log('\x1b[32m', '打包完成🎉🎉🎉你要的都在 release 目录里🤪🤪🤪');
exit();
}
});
})
.catch(async error => {
if (error.includes?.('HttpError')) {
}
console.log('\x1b[31m', '打包失败,错误信息:', error);
exit();
});
24 changes: 23 additions & 1 deletion src/app/electron-main/updater.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
// import { dialog } from 'electron';
import log from 'electron-log';
import { autoUpdater } from 'electron-updater';

import { ELETRON_APP_CONFIG } from '../../environment';

const appVersion = require('../../../package.json').version;

export class EoUpdater {
constructor() {
this.watchLog();
autoUpdater.setFeedURL({
provider: 'generic',
url: 'https://data.postcat.com/download/'
url: ELETRON_APP_CONFIG.BASE_DOWNLOAD_URL
});
// 是否自动更新
// autoUpdater.autoDownload = window.pc.getExtensionSettings('common.app.autoUpdate') !== false;
if (appVersion.includes('beta')) autoUpdater.channel = 'beta';
console.log('appVersion', appVersion, autoUpdater.channel);

// autoUpdater.on('update-downloaded', info => {
// log.info('Update downloaded.');

// // The update will automatically be installed the next time the
// // app launches. If you want to, you can force the installation
// // now:
// const dialogOpts = {
// type: 'info',
// buttons: ['重启', '稍后'],
// title: '版本升级',
// message: '有新版本可用了',
// detail: `新版本 (${info.version}) 已经下载,重启并更新.`
// };

// dialog.showMessageBox(dialogOpts).then(returnValue => {
// if (returnValue.response === 0) autoUpdater.quitAndInstall(false, true);
// });
// });
}
check() {
autoUpdater.checkForUpdatesAndNotify();
Expand Down
1 change: 1 addition & 0 deletions src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export const ELETRON_APP_CONFIG = {
// MOCK_URL: 'http://8.219.85.124:5000',
NODE_SERVER_PORT: 4201,
BASE_DOWNLOAD_URL: 'https://data.postcat.com/download/'
// BASE_DOWNLOAD_URL: 'http://127.0.0.1:8080'
} as const;
Loading

0 comments on commit 976f3ff

Please sign in to comment.