Files
srt-streamer/scripts/fix-wincodeSign.js
admin bc65186637 build: add Windows portable EXE packaging scripts
- scripts/build-icon.js — generates icon.png/ico/tray-icon.png
  from pure Node.js (no dependencies, zlib + PNG/ICO encoder)
- scripts/fix-wincodeSign.js — pre-populates electron-builder
  winCodeSign cache by extracting the .7z while ignoring macOS
  symlinks (which fail on Windows without SeCreateSymbolicLink)
- package.json: add fix-wincodeSign script, cross-env, electron-builder
  downgraded to v24 (stable portable target), CSC signing disabled

Build: npm run build:win → dist-electron/SRT-Streamer-Portable-1.0.0.exe

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 01:12:33 +03:00

111 lines
3.9 KiB
JavaScript

/**
* Downloads winCodeSign-2.6.0.7z and extracts it WITHOUT symlinks
* into the electron-builder cache, so electron-builder doesn't re-download.
*
* Run once: node scripts/fix-wincodeSign.js
*/
'use strict'
const https = require('https')
const http = require('http')
const fs = require('fs')
const path = require('path')
const os = require('os')
const { execFileSync } = require('child_process')
const VERSION = 'winCodeSign-2.6.0'
const URL_7Z = `https://github.com/electron-userland/electron-builder-binaries/releases/download/${VERSION}/${VERSION}.7z`
const CACHE = path.join(os.homedir(), 'AppData', 'Local', 'electron-builder', 'Cache', 'winCodeSign', VERSION)
const TMP_7Z = path.join(os.tmpdir(), `${VERSION}.7z`)
const SEVEN_ZIP = path.join(__dirname, '..', 'node_modules', '7zip-bin', 'win', 'x64', '7za.exe')
function download(url, dest, redirects = 0) {
return new Promise((resolve, reject) => {
if (redirects > 5) return reject(new Error('Too many redirects'))
console.log(`Downloading${redirects > 0 ? ' (redirect)' : ''}: ${url}`)
const proto = url.startsWith('https') ? https : http
const req = proto.get(url, { headers: { 'User-Agent': 'node' } }, res => {
if (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307 || res.statusCode === 308) {
return download(res.headers.location, dest, redirects + 1).then(resolve).catch(reject)
}
if (res.statusCode !== 200) return reject(new Error(`HTTP ${res.statusCode}`))
const total = parseInt(res.headers['content-length'] || '0', 10)
let received = 0
const out = fs.createWriteStream(dest)
res.on('data', chunk => {
received += chunk.length
if (total > 0) {
const pct = Math.round(received / total * 100)
process.stdout.write(`\r ${pct}% (${(received/1024/1024).toFixed(1)} MB) `)
}
})
res.pipe(out)
out.on('finish', () => { process.stdout.write('\n'); resolve() })
out.on('error', reject)
})
req.on('error', reject)
})
}
async function main() {
// Already extracted?
const nsisBin = path.join(CACHE, 'windows', 'nsis', 'Bin', 'makensis.exe')
if (fs.existsSync(nsisBin)) {
console.log('✓ winCodeSign already cached at:', CACHE)
return
}
console.log('=== Fixing winCodeSign cache ===')
console.log('Cache target:', CACHE)
// Download
if (!fs.existsSync(TMP_7Z)) {
await download(URL_7Z, TMP_7Z)
} else {
console.log('Using cached download:', TMP_7Z)
}
// Extract — ignoring exit code 1 or 2 (only symlinks fail, all real binaries extract fine)
fs.mkdirSync(CACHE, { recursive: true })
console.log('Extracting…')
try {
execFileSync(SEVEN_ZIP, ['x', '-y', '-bd', TMP_7Z, `-o${CACHE}`], {
stdio: ['ignore', 'pipe', 'pipe']
})
} catch (e) {
// Exit code 1 = warnings, exit code 2 = fatal but only for macOS symlinks — safe to ignore
if (e.status !== 1 && e.status !== 2) throw e
console.log(' (macOS symlinks skipped — expected on Windows, continuing…)')
}
// Create placeholder empty files for the macOS symlinks that 7-Zip can't create
const macSymlinks = [
'darwin/10.12/lib/libcrypto.dylib',
'darwin/10.12/lib/libssl.dylib',
]
for (const rel of macSymlinks) {
const full = path.join(CACHE, rel)
if (!fs.existsSync(full)) {
fs.mkdirSync(path.dirname(full), { recursive: true })
fs.writeFileSync(full, '')
console.log(' Created placeholder:', rel)
}
}
// Verify NSIS was extracted
if (fs.existsSync(nsisBin)) {
console.log('✓ NSIS extracted successfully:', nsisBin)
} else {
// List what we got
console.log('Contents of cache:')
const list = fs.readdirSync(CACHE)
list.forEach(f => console.log(' ', f))
}
console.log('Done! Run npm run build:win again.')
}
main().catch(e => { console.error('ERROR:', e.message); process.exit(1) })