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:
"C:/local/libs/Resource Hacker/resourcehacker.exe" -addoverwrite myapp-noicon.exe, myapp.exe, myicon.ico, ICONGROUP,MAINICON,0
Is there any sort of protection on pkg that would explain that behaviour?
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 .pkg-cache directory of your user profile. Please try.
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 master branch.
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 .pkg-cache directory.
@igorklopov could you point the commit that should have fixed this issue in pkg@4 in order that someone could investigate?
Thanks!
EDIT: I use rcedit package on the executable and when I try to start it after icon change, I get the following error:
Pkg: Error reading from file.
Like it seems that changing resources on .pkg-cache binaries works, maybe an easy improvement should be to let users pass rcedit options and, before pkg generation:
rcedit on itSince it seems that packer class is fetching offsets in binary files, maybe this is the only way to change stuff on the executable.
Can @igorklopov or someone with a good knowledge on pkg code bring some light on this?
I made a custom build script to customize my executable. Maybe it will be useful for someone else :wink:
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.
@kspearrin
I was able to replace the icon of the packaged exe using the Resource Hacker UI just fine.
Command line is a different story, however...
@acailly
Does this still work with the currently available versions of Resource Hacker?
Because all I get is:
Error: Command failed: D:\development\github\spotify-ad-blocker\node_modules\node-resourcehacker\ResourceHacker.exe -addoverwrite spotify-ad-blocker.exe, out.exe, spotify_ad_blocker_icon_hC4_icon.ico, ICONGROUP, 1,
The following works but corrupts the exe (maybe it's the name for the ICONGROUP. But the ResourceHacker CLI requires that to be specified...):
ResourceHacker.exe -open spotify-ad-blocker.exe -action addoverwrite -save out.exe -res spotify_ad_blocker_icon_hC4_icon.ico -mask ICONGROUP,Dummy,1,
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 https://github.com/zeit/pkg/issues/151#issuecomment-376520519, with only 16x16, 32x32, 48x48, 64x64 and 128x128.
You can update the icon from command line with:
ResourceHacker.exe -open app-no-icon.exe -save app-icon.exe -action addoverwrite -res icon.ico -mask ICONGROUP,1
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.
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:
ResourceHacker.exe -open app-no-icon.exe -save app-icon.exe -action addoverwrite -res icon.ico -mask ICONGROUP,1This 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 [email protected] to get icon change working again. [email protected] results in Pkg: Error reading from file. after changing the icon with ResourceHacker 5.1.7.
Same. I had to revert to [email protected] to get it to work again while [email protected] 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 pkg bootstrapping by editing the PE image after the fact but it will never work in general or across platforms. You can compile an rc file to a res on any system with GNU binutils.
I'm using [email protected] 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:
https://stackoverflow.com/a/58716971/4887252
just as a workaround, maybe it will be useful to someone
Most helpful comment
I made a custom build script to customize my executable. Maybe it will be useful for someone else :wink: