From a35c3593df19e5916222e7959c07e2aab8c6e5b2 Mon Sep 17 00:00:00 2001 From: Cosmo Myzrail Gorynych <admin@nersta.ru> Date: Sun, 16 Jun 2024 10:21:06 +0300 Subject: [PATCH 1/2] :sparkles: Set icons and metadata to Windows executables --- images/defaultIcon.png | Bin 0 -> 22233 bytes package-lock.json | 58 ++++++++++++++++++++++++++- package.json | 2 + src/modules/bundler.js | 17 ++++++++ src/modules/exepatch.js | 86 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 images/defaultIcon.png create mode 100644 src/modules/exepatch.js diff --git a/images/defaultIcon.png b/images/defaultIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..65d9c01df715c92a8f859ef924531fd9f5c85107 GIT binary patch literal 22233 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 HyU70m<F;Qn literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index 5e1fdca..40a54cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "license": "MIT", "dependencies": { "@electron/asar": "^3.0.3", - "anymatch": "^3.1.3", "archiver": "^4.0.2", "chalk": "^4.1.0", "chokidar": "^3.5.1", @@ -20,7 +19,9 @@ "edit-json-file": "^1.6.2", "follow-redirects": "^1.13.1", "fs-extra": "^9.0.1", + "png2icons": "^2.0.1", "recursive-readdir": "^2.2.2", + "resedit": "^2.0.2", "spawn-command": "^0.0.2-1", "tcp-port-used": "^1.0.2", "uuid": "^8.3.2", @@ -1187,6 +1188,19 @@ "node": ">=0.10.0" } }, + "node_modules/pe-library": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-1.0.1.tgz", + "integrity": "sha512-nh39Mo1eGWmZS7y+mK/dQIqg7S1lp38DpRxkyoHf0ZcUs/HDc+yyTjuOtTvSMZHmfSLuSQaX945u05Y2Q6UWZg==", + "engines": { + "node": ">=14", + "npm": ">=7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -1230,6 +1244,14 @@ "node": ">=0.10.0" } }, + "node_modules/png2icons": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/png2icons/-/png2icons-2.0.1.tgz", + "integrity": "sha512-GDEQJr8OG4e6JMp7mABtXFSEpgJa1CCpbQiAR+EjhkHJHnUL9zPPtbOrjsMD8gUbikgv3j7x404b0YJsV3aVFA==", + "bin": { + "png2icons": "png2icons-cli.js" + } + }, "node_modules/prettier": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", @@ -1290,6 +1312,22 @@ "node": ">=6.0.0" } }, + "node_modules/resedit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-2.0.2.tgz", + "integrity": "sha512-UKTnq602iVe+W5SyRAQx/WdWMnlDiONfXBLFg/ur4QE4EQQ8eP7Jgm5mNXdK12kKawk1vvXPja2iXKqZiGDW6Q==", + "dependencies": { + "pe-library": "^1.0.1" + }, + "engines": { + "node": ">=14", + "npm": ">=7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2492,6 +2530,11 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, + "pe-library": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-1.0.1.tgz", + "integrity": "sha512-nh39Mo1eGWmZS7y+mK/dQIqg7S1lp38DpRxkyoHf0ZcUs/HDc+yyTjuOtTvSMZHmfSLuSQaX945u05Y2Q6UWZg==" + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -2520,6 +2563,11 @@ "pinkie": "^2.0.0" } }, + "png2icons": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/png2icons/-/png2icons-2.0.1.tgz", + "integrity": "sha512-GDEQJr8OG4e6JMp7mABtXFSEpgJa1CCpbQiAR+EjhkHJHnUL9zPPtbOrjsMD8gUbikgv3j7x404b0YJsV3aVFA==" + }, "prettier": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", @@ -2562,6 +2610,14 @@ "minimatch": "^3.0.5" } }, + "resedit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-2.0.2.tgz", + "integrity": "sha512-UKTnq602iVe+W5SyRAQx/WdWMnlDiONfXBLFg/ur4QE4EQQ8eP7Jgm5mNXdK12kKawk1vvXPja2iXKqZiGDW6Q==", + "requires": { + "pe-library": "^1.0.1" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", diff --git a/package.json b/package.json index 85328a6..18f040a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,9 @@ "edit-json-file": "^1.6.2", "follow-redirects": "^1.13.1", "fs-extra": "^9.0.1", + "png2icons": "^2.0.1", "recursive-readdir": "^2.2.2", + "resedit": "^2.0.2", "spawn-command": "^0.0.2-1", "tcp-port-used": "^1.0.2", "uuid": "^8.3.2", diff --git a/src/modules/bundler.js b/src/modules/bundler.js index 5848746..1ba3352 100644 --- a/src/modules/bundler.js +++ b/src/modules/bundler.js @@ -6,6 +6,7 @@ const config = require('./config'); const constants = require('../constants'); const frontendlib = require('./frontendlib'); const utils = require('../utils'); +const {patchWindowsExecutable} = require('./exepatch'); async function createAsarFile() { utils.log(`Generating ${constants.files.resourceFile}...`); @@ -76,6 +77,22 @@ module.exports.bundleApp = async (isRelease, copyStorage) => { } } + utils.log('Patching windows executables...'); + try { + await Promise.all(Object.keys(constants.files.binaries.win32).map(async (arch) => { + const origBinaryName = constants.files.binaries.win32[arch]; + const winPath = `${buildDir}/${binaryName}/${origBinaryName.replace('neutralino', binaryName)}`; + if (await fse.exists(winPath)) { + await patchWindowsExecutable(winPath); + } + })) + } + catch (err) { + console.error(err); + utils.error('Could not patch windows executable'); + process.exit(1); + } + for (let dependency of constants.files.dependencies) { fse.copySync(`bin/${dependency}`, `${buildDir}/${binaryName}/${dependency}`); } diff --git a/src/modules/exepatch.js b/src/modules/exepatch.js new file mode 100644 index 0000000..53964ec --- /dev/null +++ b/src/modules/exepatch.js @@ -0,0 +1,86 @@ +const fse = require('fs-extra'); +const png2icons = require('png2icons'); + +const config = require('./config'); +// 1033 means "English (United States)" locale in Windows +const EN_US = 1033; + +const getWindowsMetadata = (config) => { + const versionStrings = { + CompanyName: config.author, + FileDescription: config.description ?? 'A Neutralinojs application', + ProductVersion: config.version, + LegalCopyright: config.copyright ?? + `Copyright © ${new Date().getFullYear()} ${config.author ?? 'All rights reserved.'}`, + InternalName: config.cli.binaryName, + OriginalFilename: config.cli.binaryName, + ProductName: config.applicationName ?? config.cli.binaryName, + SpecialBuild: config.cli.binaryName, + }; + // Strip away any undefined values from the versionStrings object + // in case some configuration options are missing. + Object.keys(versionStrings).forEach((option) => { + if (versionStrings[option] === undefined) { + delete versionStrings[option]; + } + }); + return versionStrings; +}; + +/** + * Reads the specified png file and returns a buffer of a converted ICO file. + */ +const convertPngToIco = async (src) => { + const icon = await fse.readFile(src); + return png2icons.createICO(icon, png2icons.HERMITE, 0, true, true); +} + +/** + * Edits the Windows executable with an icon + * and changes its metadata to include the app's name and version. + * + * @param {string} src The path to the .exe file + */ +const patchWindowsExecutable = async (src) => { + const resedit = await import('resedit'); + // pe-library is a direct dependency of resedit + const peLibrary = await import('pe-library'); + const configObj = config.get(); + // Create an executable object representation of the .exe file and get its resource object + const exe = peLibrary.NtExecutable.from(await fse.readFile(src)); + const res = peLibrary.NtExecutableResource.from(exe); + + const iconPath = configObj.applicationIcon ?? + configObj?.modes?.window?.icon ?? // Get the icon from the window's config + `${__dirname}/../../images/defaultIcon.png`; // Default to a neutralinojs icon + const icoBuffer = await convertPngToIco(iconPath); + // Create an icon file that contains the icon + const iconFile = resedit.Data.IconFile.from(icoBuffer); + // Put the group into the resource + resedit.Resource.IconGroupEntry.replaceIconsForResource( + res.entries, + // 0 is the default icon group + 0, + EN_US, + iconFile.icons.map(i => i.data) + ); + + // Fill in version info + const vi = resedit.Resource.VersionInfo.createEmpty(); + const [major, minor, patch] = (configObj.version ?? '1.0.0').split("."); + vi.setFileVersion(major ?? 1, minor ?? 0, patch ?? 0, 0, EN_US); + vi.setStringValues({ + lang: EN_US, + codepage: 1200 + }, getWindowsMetadata(configObj)); + vi.outputToResourceEntries(res.entries); + // Write the modified resource to the executable object + res.outputResource(exe); + // Output the modified executable to the original file path + const outBuffer = Buffer.from(exe.generate()); + await fse.writeFile(src, outBuffer); +} + +module.exports = { + patchWindowsExecutable +}; \ No newline at end of file From 28f33c614c089b9612b373b395d96d152115a2df Mon Sep 17 00:00:00 2001 From: Cosmo Myzrail Gorynych <admin@nersta.ru> Date: Mon, 19 Aug 2024 22:53:56 +1200 Subject: [PATCH 2/2] :zap: Update the code to support Node.js v12+ and fix the code when only an icon in modes.window.icon was specified --- src/modules/exepatch.js | 57 ++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/modules/exepatch.js b/src/modules/exepatch.js index 53964ec..f7d5813 100644 --- a/src/modules/exepatch.js +++ b/src/modules/exepatch.js @@ -1,20 +1,34 @@ const fse = require('fs-extra'); const png2icons = require('png2icons'); +const path = require('path'); const config = require('./config'); // 1033 means "English (United States)" locale in Windows const EN_US = 1033; +// works like `a ?? b ?? c ?? ...` +const pickNotNullish = (...values) => { + for (let i = 0; i < values.length - 1; i++) { + if (values[i] !== undefined && values[i] !== null) { + return values[i]; + } + } + return values[values.length - 1]; +} + const getWindowsMetadata = (config) => { + const copyright = pickNotNullish( + config.copyright, + `Copyright © ${new Date().getFullYear()} ${pickNotNullish(config.author, 'All rights reserved.')}` + ); const versionStrings = { CompanyName: config.author, - FileDescription: config.description ?? 'A Neutralinojs application', + FileDescription: pickNotNullish(config.description, 'A Neutralinojs application'), ProductVersion: config.version, - LegalCopyright: config.copyright ?? - `Copyright © ${new Date().getFullYear()} ${config.author ?? 'All rights reserved.'}`, + LegalCopyright: copyright, InternalName: config.cli.binaryName, OriginalFilename: config.cli.binaryName, - ProductName: config.applicationName ?? config.cli.binaryName, + ProductName: pickNotNullish(config.applicationName, config.cli.binaryName), SpecialBuild: config.cli.binaryName, }; // Strip away any undefined values from the versionStrings object @@ -50,9 +64,28 @@ const patchWindowsExecutable = async (src) => { const exe = peLibrary.NtExecutable.from(await fse.readFile(src)); const res = peLibrary.NtExecutableResource.from(exe); - const iconPath = configObj.applicationIcon ?? - configObj?.modes?.window?.icon ?? // Get the icon from the window's config - `${__dirname}/../../images/defaultIcon.png`; // Default to a neutralinojs icon + // If an icon was not set for the project, try to get the icon from the window's config + let windowIcon = null; + if (configObj.modes && configObj.modes.window && configObj.modes.window.icon) { + windowIcon = configObj.modes.window.icon; + // Do not use non-PNG window icons. + if (windowIcon.split('.').pop().toLowerCase() !== 'png') { + windowIcon = null; + } else { + // Remove the leading slash if it exists, we need a path relative to CWD. + if (windowIcon[0] === '/') { + windowIcon = windowIcon.slice(1); + } + // Get the path from the resources directory relative to CWD. + windowIcon = path.join(process.cwd(), windowIcon); + } + } + + const iconPath = pickNotNullish( + configObj.applicationIcon, + windowIcon, + `${__dirname}/../../images/defaultIcon.png` // Default to a neutralinojs icon + ); const icoBuffer = await convertPngToIco(iconPath); // Create an icon file that contains the icon const iconFile = resedit.Data.IconFile.from(icoBuffer); @@ -67,8 +100,14 @@ const patchWindowsExecutable = async (src) => { // Fill in version info const vi = resedit.Resource.VersionInfo.createEmpty(); - const [major, minor, patch] = (configObj.version ?? '1.0.0').split("."); - vi.setFileVersion(major ?? 1, minor ?? 0, patch ?? 0, 0, EN_US); + const [major, minor, patch] = pickNotNullish(configObj.version, '1.0.0').split("."); + vi.setFileVersion( + pickNotNullish(major, 1), // Version number + pickNotNullish(minor, 0), + pickNotNullish(patch, 0), + 0, // Revision number, isn't used in most JS applications so use a 0. + EN_US + ); vi.setStringValues({ lang: EN_US, codepage: 1200