Ana içeriğe geç

Electron Builder ile Entegrasyon

Bu belge, uzaktan kod imzalama hizmetinin Electron uygulamasının derleme sürecine nasıl entegre edileceğini, electron-builder kullanılarak Windows platformundaki kurulum paketleri ve yürütülebilir dosyaların otomatik olarak nasıl imzalanacağını açıklar.

İpucu

Burada test için açık kaynaklı bir proje kullanılmıştır vite-electron-builder.

Ön Koşullar

  1. Kullanılabilir bir sslTrus uzaktan kod imzalama hizmeti hesabına sahip olunması ve geçerli erişim kimlik bilgilerinin (AK/SK) edinilmiş olması.
  2. İmzalama için kullanılabilir bir uzaktan kod imzalama hizmetinin bulunması.
  3. Projenin electron-builder temel alınarak derlenmesi.

Entegrasyon Adımları

Adım 1: Electron Builder Dosyasını Yapılandırma

Electron proje kök dizininde, electron-builder.mjs (veya electron-builder.yml/config.js) dosyasını bulun ve değiştirin.

Aşağıda eksiksiz bir yapılandırma örneği verilmiştir; varsayılan yapılandırmayı değiştirip signtoolOptions.sign özel imzalama yöntemini eklemeniz gerekir.

export default /** @type import('electron-builder').Configuration */
({
win: {
target: [
{
target: 'nsis',
arch: ['x64'],
},
],
signtoolOptions: {
sign: customSign,
signingHashAlgorithms: ['sha256'], // 这里只需要选择一个即可,实际的双签由 customSign 执行
},
},
});

async function customSign(configuration) {
const srcPath = configuration.path;
const cwd = process.cwd();
const relPath = relative(cwd, srcPath);

// 设置环境变量 export SIGNTOOL_ACCESS_KEY='' SIGNTOOL_ACCESS_SECRET='' SIGNTOOL_CERT_CODE=''
const {SIGNTOOL_ACCESS_KEY, SIGNTOOL_ACCESS_SECRET, SIGNTOOL_CERT_CODE} = process.env;
if (!SIGNTOOL_ACCESS_KEY || !SIGNTOOL_ACCESS_SECRET || !SIGNTOOL_CERT_CODE) {
console.error(`[ERROR] Missing environment variables: SIGNTOOL_ACCESS_KEY, SIGNTOOL_ACCESS_SECRET, SIGNTOOL_CERT_CODE`);
return;
}

// 下载对应平台的命令行工具
const signtoolPath = join(cwd, 'signtool', 'signtool');
const dir = dirname(srcPath);
const ext = extname(srcPath);
const name = basename(srcPath, ext);
const randomStr = randomBytes(4).toString('hex');
const tempPath = join(dir, `${name}-${randomStr}${ext}`);

const startTime = Date.now();

try {
console.log(`[SIGNING] ${relPath}`);

const logFilePath = join(cwd, 'signtool', name + '.log');
writeFileSync(logFilePath, `Source: ${srcPath}\nTime: ${new Date().toLocaleString()}\n\n`);
const logFd = openSync(logFilePath, 'a');

// 签名默认不会覆盖源文件,且目标文件不存在,所以先将源文件重命名为临时文件
renameSync(srcPath, tempPath);

// 参数可参考 signtool 命令行解析
const command = [
signtoolPath,
'sign',
`-k "${SIGNTOOL_ACCESS_KEY}"`,
`-s "${SIGNTOOL_ACCESS_SECRET}"`,
`-c "${SIGNTOOL_CERT_CODE}"`,
`-f "${tempPath}"`, // 源文件
`-o "${srcPath}"`, // 目标文件
'--nest=true', // 嵌套签名
'--sha1=false', // sha1 签名,对于 bool 值的参数传递需要使用 arg=value 的方式,不可使用 arg value 的形式
'--timestamp http://timestamp.sectigo.com',
'--sha2=true', // sha2 签名
'--timestamp-rfc3161 http://timestamp.sectigo.com',
].join(' ');

// 将 signtool 的日志输出到文件
execSync(command, {stdio: ['ignore', logFd, logFd]});

// 删除临时文件
rmSync(tempPath, {force: true});

const duration = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`[SUCCESS] Finished in ${duration}s -> ${relPath}`);
} catch (e) {
console.error(`[FAILURE] Failed to sign: ${relPath}`);
console.error(` Check log: signtool/${name}.log`);
process.exit(1);
}
}

Adım 2: Derleme

Yapılandırma tamamlandıktan sonra Electron derleme komutunuzu çalıştırın. Derleme sürecinde yukarıdaki özel imzalama işlevi otomatik olarak çağrılacaktır.

# 示例:构建 Windows 64位 安装包
npm run compile -- --win --x64
# 或使用 npx
npx electron-builder build --config electron-builder.mjs --win --x64

Derleme Süreci

Uzaktan kod imzalama hizmetinin Electron Builder ile entegrasyonu

Derleme Sonucu

Kurulum paketi ve ana program imzalanmıştır

Uzaktan kod imzalama hizmetinin Electron Builder ile entegrasyonu

Uzaktan kod imzalama hizmetinin Electron Builder ile entegrasyonu