-
Notifications
You must be signed in to change notification settings - Fork 1k
Changing icon in windows #91
Comments
We would also like a fix for this issue |
A temporary solution can be to apply resources not to final executables, but to base binaries located at |
What is the difference between the final executables and the base binaries? |
The temporary solution worked for us, looking forward to actual solution later. |
Fixed in |
Fixed in pkg@4. |
Somehow running the exe with resource hacker on windows still corrupt the packaged file. But works well by updating the fetched-v8.9.0-win-x64 within the |
@igorklopov could you point the commit that should have fixed this issue in pkg@4 in order that someone could investigate? EDIT: I use
|
Like it seems that changing resources on
Since it seems that |
I made a custom build script to customize my executable. Maybe it will be useful for someone else 😉 const fs = require("fs");
const resourceHacker = require("node-resourcehacker");
const execSync = require("child_process").execSync;
const customIconPath = "icon.ico";
const resourceHackerPath = "resource_hacker.zip"; //This file must exist, if not download it at http://www.angusj.com/resourcehacker/resource_hacker.zip
const originalPkgPrecompiledBinaries =
"./pkg-cache/v2.5/fetched-v6.11.5-win-x64.original";
const customizedPkgPrecompiledBinaries =
"./pkg-cache/v2.5/fetched-v6.11.5-win-x64";
process.env["SOURCE_RESOURCE_HACKER"] = resourceHackerPath;
console.log("Download pkg precompiled libraries");
downloadOriginalPkgPrecompiledBinaries();
console.log("Customize pkg precompiled libraries");
customizePkgPrecompiledBinaries();
console.log("Build customized executables");
buildCustomizedExecutables();
console.log("Done");
function downloadOriginalPkgPrecompiledBinaries() {
if (!fs.existsSync(originalPkgPrecompiledBinaries)) {
executePkg("temp.exe");
//Add .original extension
fs.renameSync(
customizedPkgPrecompiledBinaries,
originalPkgPrecompiledBinaries
);
//Remove temp.exe
fs.unlinkSync("temp.exe");
}
}
function customizePkgPrecompiledBinaries() {
resourceHacker(
{
operation: "addoverwrite",
input: "./pkg-cache/v2.5/fetched-v6.11.5-win-x64",
output: "./pkg-cache/v2.5/fetched-v6.11.5-win-x64",
resource: customIconPath,
resourceType: "ICONGROUP",
resourceName: "1"
},
err => {
if (err) {
return console.error(err);
}
}
);
}
function buildCustomizedExecutables() {
executePkg("GeneUP-Thermal_Performance_Tool.exe");
}
function executePkg(exeName) {
execSync(
"yarn run cross-env PKG_CACHE_PATH=./pkg-cache pkg index.js --target win --output " +
exeName
);
} |
@acailly thanks for sharing! |
@igorklopov This is still broken in v4 , only way for it to work is by using resource hacker on the executable in pkg cache prior to building the exe. |
I was able to replace the icon of the packaged exe using the Resource Hacker UI just fine. Does this still work with the currently available versions of Resource Hacker? Because all I get is: The following works but corrupts the exe (maybe it's the name for the ICONGROUP. But the ResourceHacker CLI requires that to be specified...): |
Hi all, I was checking how the pkg builds the binary and it seems that node.js builds the node.exe and then the pkg "transfers" the content into the executable. Thats why we have base metadata on the node.exe Here a source code where you can find icon definition (+ metadata): https://github.com/nodejs/node/blob/8b4af64f50c5e41ce0155716f294c24ccdecad03/src/res/node.rc The pkg would have to overwrite the node.rc file and build the node.exe on every build. |
@s-h-a-d-o-w I just downloaded the last version of ressource hacker and tried again, it worked I don't have much time to investigate more on this since I don't work anymore on this project, sorry |
Just updating with what currently works. First create an icon like explained on #151 (comment), with only 16x16, 32x32, 48x48, 64x64 and 128x128. You can update the icon from command line with:
This works with ResourceHacker 5.1.7 and pkg 4.4.0. RH works on Wine 4.0, but it requires an X display even when it supposedly runs on command line only. You can workaround with a Xvfb. |
I had to revert to pkg@4.3.4 to get icon change working again. pkg@4.4.0 results in |
Same. I had to revert to pkg@4.3.7 to get it to work again while pkg@4.4.0 results in the same error as above. |
As @pionl mentioned above, the right way to create a branded executable is to build node with a custom resource file. You might get lucky and not break the |
I'm using pkg@4.4.2 and this appears to still be an issue. Our solution is to download the binary, modify it first, then run pkg.exec: (with inspiration from @acailly) const resourceHackerPath = path.join(__dirname, "ResourceHacker.exe"); //This file must exist, if not download it at http://www.angusj.com/resourcehacker/resource_hacker.zip
const pkgCachePath = "./pkg-cache";
process.env["SOURCE_RESOURCE_HACKER"] = resourceHackerPath;
process.env["PKG_CACHE_PATH"] = pkgCachePath;
const execSync = require("child_process").execSync;
const fs = require("fs-extra");
const pkg = require("pkg");
const pkgfetch = require("pkg-fetch");
const customIconPath = "iconset.ico";
const specificNodeVersion = "12.13.1"; // this must be the full release version, and be supported by
pkg https://github.com/zeit/pkg-fetch/blob/master/patches/patches.json
const originalPkgPrecompiledBinaries =`${pkgCachePath}/v2.6/fetched-v${specificNodeVersion}-win-x64.original`;
const customizedPkgPrecompiledBinaries =`${pkgCachePath}/v2.6/fetched-v${specificNodeVersion}-win-x64`;
async function downloadOriginalPkgPrecompiledBinaries() {
if (!fs.existsSync(originalPkgPrecompiledBinaries)) {
await pkgfetch.need({nodeRange:`node${specificNodeVersion}`,platform:"win",arch:"x64"});
}
}
async function customizePkgPrecompiledBinariesVersionInfo(s) {
execSync(`${resourceHackerPath} -open ./resources/WinSW/${s}/version-info.rc -save ./resources/WinSW/${s}/version-info.res -action compile`);
execSync(`${resourceHackerPath} -open ./pkg-cache/v2.6/fetched-v${specificNodeVersion}-win-x64.original -save ./pkg-cache/v2.6/fetched-v${specificNodeVersion}-win-x64 -resource ./resources/WinSW/${s}/version-info.res -action addoverwrite`);
}
async function customizePkgPrecompiledBinariesIcon() {
execSync(`${resourceHackerPath} -open ./pkg-cache/v2.6/fetched-v${specificNodeVersion}-win-x64.original -save ./pkg-cache/v2.6/fetched-v${specificNodeVersion}-win-x64 -resource ${customIconPath} -action addoverwrite -mask ICONGROUP,1,`);
}
async function customizePkgPrecompiledBinaries(s) {
await customizePkgPrecompiledBinariesVersionInfo(s);
await fs.rename(
customizedPkgPrecompiledBinaries,
originalPkgPrecompiledBinaries
);
await customizePkgPrecompiledBinariesIcon();
}
async function package() {
console.log("Download pkg precompiled libraries");
await downloadOriginalPkgPrecompiledBinaries();
for (let s of ["Agent", "Server"]) {
await _pack(s); // runs pkg.exec to actually create the packaged .exe files
}
} |
This is a big shortcoming. |
as an option generate exe and also customize version-info.rc file using batch: |
Doesn't work anymore. |
seconding this, anyone have a solution?
this still works well for changing version info, but how can we change icon? |
We've built a solution, similar to the ones as described by @acailly and @klugerama; for changing the icon, and the file metadata (version, description, etc...) of the final executable by first updating the precompiled node binaries. I'll try to describe the workflow -- which works perfectly for us -- as best as I can. We're using Let's take a quick peek at the codebase's directory structure, so you can better comprehend the code that follows.
|
Hi there! I just want to simply point out that NONE of the above work anymore because of the commit 629cc71d268509ceb242440b89ffe2279a14a89c which adds a check for the file hashes of the prebuilt binaries. [NOTE] For anyone wondering what versions he/she should downgrade to, any pkg-fetch version lower than 3.0.3 and any pkg version lower than or equal to 5.0.0 will be fine. |
Found this over in the issues of patch package for those who might come to find a workaround from the update. https://github.com/vercel/pkg-fetch/issues/188#issuecomment-857506807 |
Summary of workaround from vercel/pkg-fetch#188:
|
A simpler, more universal version with fewer hard-coded params, updated to the recent changes:
|
From a legal point of view - is it OK to overwrite just any file property of a bundled Node.js application (e.g. version, description, copyright, original filename)? |
That worked perfectly to me, thanks! |
Why go through all this trouble when you can simply use Here's an example of how I'm utilizing const fs = require("fs");
const path = require("path");
const ResEdit = require('resedit');
function windowsPostBuild(output) {
const exe = ResEdit.NtExecutable.from(fs.readFileSync(output));
const res = ResEdit.NtExecutableResource.from(exe);
const iconFile = ResEdit.Data.IconFile.from(fs.readFileSync(path.join(__dirname, 'icon.ico')));
ResEdit.Resource.IconGroupEntry.replaceIconsForResource(
res.entries,
1,
1033,
iconFile.icons.map(item => item.data)
);
const vi = ResEdit.Resource.VersionInfo.fromEntries(res.entries)[0];
vi.setStringValues(
{lang: 1033, codepage: 1200},
{
ProductName: 'You app name',
FileDescription: 'You app description',
CompanyName: 'My company',
LegalCopyright: `Copyright Me. MIT license.`
}
);
vi.removeStringValue({lang: 1033, codepage: 1200}, 'OriginalFilename');
vi.removeStringValue({lang: 1033, codepage: 1200}, 'InternalName');
vi.setFileVersion(1, 0, 0, 1033);
vi.setProductVersion(1, 0, 0, 1033);
vi.outputToResourceEntries(res.entries);
res.outputResource(exe);
fs.writeFileSync(output, Buffer.from(exe.generate()));
} Edit the metadata and paths to match your project and simply call |
Replace to
|
Oops. Slight mistake there while editing stuff out from my original source. Thanks for pointing that out. Fixed it on the original post. |
Lol, After changing the icon, I got this
|
I tried changing the icon with Resource hacker, but the resulting .exe does not run. Actually, it runs, but freezes immediately. Here's what I tried:
Is there any sort of protection on pkg that would explain that behaviour?
The text was updated successfully, but these errors were encountered: