nwutils / nw-builder

Build NW.js applications for Linux, MacOS and Windows
MIT License
1.68k stars 303 forks source link

Use Resource Hacker instead of rcedit #44

Closed quasado closed 10 years ago

quasado commented 10 years ago

To replace the windows icon, rcedit simply doesn't work as it generates the wrong icon resource headers resulting in ugly window icons. Using Resource Hacker with command line

ResHacker.exe -modify "Project.exe", "Project.exe", "ProgramIcon.ico", ICONGROUP, MAINICON, 0

Works perfectly generating the correct icon header and results in high quality icons.

gabepaez commented 10 years ago

I like this solution but only if we were able to bundle the executable. I would hate to create an external dependency for this.

Have you ever used this https://github.com/geo8bit/nodebob/tree/master/buildTools/ar?

RobinMalfait commented 10 years ago

What if you are on a Mac and you want to make a windows version, how are you going to run that .exe application?

gabepaez commented 10 years ago

@RobinMalfait currently Wine is required to use the existing rcedit solution. That surprisingly works while running from Windows directly does not.

This is still not ideal as there is the hanging external dependency. Any ideas for making this work cross platform without creating a dependency requirement would be very appreciated... :)

RobinMalfait commented 10 years ago

@gabepaez it would be nice to have 1 tool cross platform instead of Wine & rcedit, if I find something i'll let you know ;)

quasado commented 10 years ago

Well, the wine solution isn't bad at all I have to say. However as said, rcedit generates the wrong icon headers so your icons will ALWAYS look ugly on Windows

bastimeyer commented 10 years ago

It's not only rcedit which generates shitty icons, but also resourcehacker. If you're compiling your app for windows and you want to replace the icon with an ico file which embeds multiple icon sizes, both seem to fail. Just adding a 128x128 or a 256x256 icon will result in a very poorly downsampled 16x16 icon. That's the reason why I've skipped changing the icon for my app. As far as I know, there are no real nodejs projects (yet) which can replace the icon properly for exe files. :worried:

quasado commented 10 years ago

hu? At least for me it works perfectly with Resource Hacker and multiple icon sizes in one icon file. Doing that afterwards in Windows via Resource-hacker -> replace icon makes it perfect and generates the correct headers (the first icon header is simply wrong as it contains a single image definition only when using rcedit)

felicienfrancois commented 10 years ago

@bastimeyer You need to provide amultiple size icon file. It ships all the size correctly sampled so there is no downsampling issues. You can do it with an online tool or using gimp http://stackoverflow.com/questions/4354617/how-to-make-get-a-multi-size-ico-file

@quasado I personnaly use resourcehacker with the following command line:

-addoverwrite nw.exe, myApp.exe, myApp.ico, ICONGROUP, IDR_MAINFRAME,

with a multiple sizes icon file. The result is perfect.

For my own use I wrote a node wrapper for resourcehacker that works under linux & OS X with wine installed. 2 points I need to solve before distributing:

felicienfrancois commented 10 years ago

@gabepaez This tool https://github.com/geo8bit/nodebob/tree/master/buildTools/ar seems interesting. I succeded in using it using the following command line:

Resourcer.exe -op:upd -src:nw.exe -type:14 -name:IDR_MAINFRAME -file:myApp.ico

The pros:

The cons:

bastimeyer commented 10 years ago

@felicienfrancois Yeah I know... I've created the multisampled icon with ImageMagick (convert icon-16.png icon-32.png icon-48.png icon-256.png icon.ico) and it seems that this method fails. http://convertico.org/Multi_Image_to_one_icon/ does the job perfectly though...

gabepaez commented 10 years ago

@felicienfrancois is Resourcer.exe able to add the multiple icon sizes contained in the ico correctly without downsampling as @bastimeyer describes?

felicienfrancois commented 10 years ago

@gabepaez yes Resourcer worked with a multiple icon size file correctly without downsampling.

felicienfrancois commented 10 years ago

The main issue of rcedit is that it does not take any "path of ressource".

The node-webkit binary have by default a single size icon (48*48) on the path ICONGROUP > IDR_MAINFRAME

Setting an icon with rcedit do the following:

I don't know why and how it does that, maybe an index issue but it does not do the job correctly as windows ignore the ICONGROUP > 1 entry and use only the ICONGROUP > IDR_MAINFRAME entry

Both resourceHacker and Resourcer.exe take a "resource path" argument and succeed in keeping all the icon sizes. Unlike the command line given by quasado in the first post, the "resource path" to edit must be ICONGROUP > IDR_MAINFRAME to work. (ICONGROUP === type:14 for Resourcer.exe)

quasado commented 10 years ago

Yes, that's exactly the issue. RCEdit should actually replace the IDR_MAINFRAME with the multiple icon sizes to work correctly. So, for now, this renders the winIcon property of node webkit builder pretty useless :( I'd still vote for using Resource Hacker to make it working correctly?

gabepaez commented 10 years ago

Alright, I am all for replacing RCEdit with (Anolis Resourcer)[http://anolis.codeplex.com/] for now. This should be relatively easy and gives us a stop gap that will at least work properly on all platforms (with Wine). Does anyone have some time to implement?

felicienfrancois commented 10 years ago

@gabepaez 1°) Anolis Resourcer require .NET to work which is not trivial to install on wine (on top of the requirement of an X server).

2°) I wrote a nodejs wrapper for resource hacker that work perfectly. I have just sent an email to Angus Johnson to ask him for permission to distribute Resource Hacker with the wrapper. Maybe we could wait for his answer to choose.

3°) If we choose Anolis Resourcer, I can write the wrapper as it will just be a copy/paste of my wrapper of Resource Hacker

gabepaez commented 10 years ago

I just did some testing and though Anolis Resourcer does seem to work using a default install of wine on osx it appears to have the same issue as rcedit where the generated icon looks downsampled and jagged. We might need to hold out for Resource Hacker @felicienfrancois.

felicienfrancois commented 10 years ago

@gabepaez Do you used wine 1.7.23 (dev branch) ? As far as my info are good, .NET framework is included by default in development branch (1.7.23) but not yet in stable branch (1.6.2). On most linux server distribution, the latest wine version available through package manager is even older.

Anyway, that's strange you found that anolis downsampled the icon whereas it worked for me. Is your icon in the right format ? Does it work with Resource hacker ? How do you made your check (windows icon cache may be hard to flush) ?

gabepaez commented 10 years ago

I am just running wine 1.6.2 installed via Brew. It's possible my ico file is not in a quality format. I created it online using some random tool. I will try to find a better pre-exisiting ico out there and run it through Resource Hacker too.

felicienfrancois commented 10 years ago

I just wrote a wrapper for Anolis Resourcer: https://github.com/felicienfrancois/node-winresourcer

It could be used for node-webkit using the following code:

require("winresourcer")({
            operation: "Update",
            exeFile: "path/to/the/file.exe",
            resourceType: "Icongroup",
            resourceName: "IDR_MAINFRAME",
            resourceFile: "path/to/icon.ico"
        }, function(error) {
            // callback
        });
quasado commented 10 years ago

I am all in for integrating Resource Hacker when permission (hopefully) arrives. It doesn't require .NET and it works just perfectly. Adding another .NET layer on top of wine to just replace an icon seems to be.. erm.. overengineered :D

felicienfrancois commented 10 years ago

@quasado I agree with you but I would like to share with you some new information I have about Anolis Resourcer.

I found the documentation and it includes a comparison with Resource Hacker. The comparison is outdated (because now Resource Hacker support x64) but there are a few interesting pros of using Anolis Resourcer (for example the support of PNG icons).

Then regarding the .NET framework requirement, here my test results:

quasado commented 10 years ago

@felicienfrancois hmm yes, you're right. Especially this feature - "Intelligent Icon Merging" seems like the one we'd need here. Anyway, a whole .NET framework dependency for exchanging an icon seems to make the build step complexity one step higher :(

felicienfrancois commented 10 years ago

@quasado Well, it requires .NET framework 2.0.

So it seems to be only a matter for some linux distribution which are on an more stable & security release policy (Red Hat, Centos, ..). Additionally, on those distribution which are mostly used on server, you'll have the issue of the X requirement for both ResHacker & Resourcer.

We can assume that making things to work in such linux distribution is not trivial in any case. System admins are use to that :-) (Troll ? Not sure ...)

gabepaez commented 10 years ago

@felicienfrancois I've staged the changes (d412cd3ebf3ad9c1b245fb53a5eec0905e17f669) to replace rcedit with your node-winresourcer wrapper and it works pretty well. I am getting a warning message in the console when running from osx

fixme:wincodecs:PngDecoder_Block_GetCount 0x21e9b80,0x32f55c: stub

Do you get the same message using your wrapper? In any case, it is still properly updating the exe with the ico resource info.

I think this is our best option at the moment given that we don't have the licensing for bundling Resource Hacker and the current rcedit solution is not functioning properly while this issue has no response.

felicienfrancois commented 10 years ago

@gabepaez No I havn't this error on ubuntu 14.04 LTS (wine 1.6.2)

bastimeyer commented 10 years ago

I'm having some troubles building my app since the v0.1.2 release... The resourcer method seems to produce a corrupted .exe file. This only happens when I try to build it while using windows. Building my app for windows on linux works fine (using wine 1.6.2), which is quite surprising. The corrupted app just displays the default node-webkit ascii art page. I've tested it with two different icons: the first one only contains a single non-compressed 32bpp png image and the second one embeds four compressed 32bpp png images. Both icons work like a charm when I compile my app on linux (where I also get the fixme:wincodecs:PngDecoder_Block_GetCount 0x13e2400,0x32f538: stub messages).

felicienfrancois commented 10 years ago

Hi @bastimeyer,

bastimeyer commented 10 years ago

Win7x64 (using MinGW though), nw v10.0.1, no problems without icon replacements...

No matter which kind of icon I use, Resourcer seems to remove all the content of my app from the node-webkit executable after replacing the icon - the .exe file is ~2MiB smaller afterwards. I've tried both the CLI and GUI of Resourcer and all kinds of icon formats (< vista and >= vista, single icon and multiple icons). And as already mentioned above: all this doesn't happen while using linux and wine with the exact same configuration.

I've also encountered a bug with the path format for the -src:xyz and -file:xyz arguments. Resourcer expects the path to be in a windows specific format, but minwg uses the unix format. But I guess thats rather related to your project than this one...

felicienfrancois commented 10 years ago

@bastimeyer

To determin if it's a winresourcer bug or a node-webkit-builder one, can you try to set the icon after the node-webkit-builder build (without icon set) using the winresourcer grunt task:

npm install winresourcer --save-dev
grunt.loadNpmTasks('winresourcer');
...
grunt.initConfig({
    ...
    "winresourcer": {
        your_target: {
            operation: "Update",
            exeFile: "path/to/the/file.exe",
            resourceType: "Icongroup",
            resourceName: "IDR_MAINFRAME",
            resourceFile: "path/to/your/resource.ico"
        }
    }
    ...
});
bastimeyer commented 10 years ago

It's a Resourcer related issue...

I've tried both the CLI and GUI of Resourcer

This results in the following command line and running Resourcer with these parameters breaks my nw app... Resourcer -op:upd -src:foo.exe -type:Icongroup -name:IDR_MAINFRAME -lang:1033 -file:icon.ico

felicienfrancois commented 10 years ago

@bastimeyer Strange, It works for me.

Can you try it on the raw nw.exe (without the app in it). And if it succeed, try to build your app with the modified nw.exe. If it works, the fix in node-webkit-builder would be to set icon before packing.

If it does not work, you can also try the following:

bastimeyer commented 10 years ago

@felicienfrancois I've already reinstalled .NET Framework 4.5.1 and also played around with the parameters, but resourcer still removes the app content all the time.

Changing the build order by replacing the icon before appending the app content to the exe file has finally fixed my problems. That was a great idea :+1:

@gabepaez Do you want me to make a pull request for this?