Replacing icon in Windows *.exe from open-source platform-independent Java code
Asked Answered
G

5

9

First of all, this is not a duplicate of the very common question of making an EXE from Java classes. I do not need to do that.

To solve NetBeans RFE #64612 without manual steps I need a Java (6+) library which can take an existing Windows *.exe file and replace its icon with a substitute in a common format. The executable, which is generic and prebuilt (distributed in binary form), already knows how to load an application-specific config file and then start the JRE with various application JARs etc.; the only problem is that it has a generic icon, and I would like to replace that icon as part of a pure Java build with an application-specific icon, so it looks prettier.

The library must be available under a nonviral open-source license; cross-platform (must run on Windows, Linux, Mac, Solaris) so cannot fork some OS-specific helper tool; and must accept PNG input, though the EXE must work on XP so according to Wikipedia should embed BMP format. At a high level, supposing Ant as a build tool, I would like something like this:

<replaceicon from="app.exe" to="hello.exe" icon="hello.png"/>

Does anyone know if a tool matching these specifications already exists? From various web searches I found Launch4J, but this appears to just fork windres for the real work, thus not trivially portable. I found JSmooth which looks more promising - appears to include Java code to handle the ICO codec and manipulate PE files - but it is GPL. WinRun4J looks to use native code for icon manipulation, though I had a hard time following its sources. Jimi supposedly handles the ICO format (for that matter the standard javax.imageio seems to as well) but I guess has no facility for updating PE resources.

Giraffe answered 28/12, 2011 at 17:40 Comment(1)
Related question: https://mcmap.net/q/173689/-how-to-change-jframe-icon-duplicateNaga
N
2

According to my Eclipse Rich Client Platform product builder,

  • Linux requires an XPM icon
  • MacOSX requires an ICNS file
  • Solaris requires 4 PM icons, Large, Medium, Small, and Tiny
  • Windows (32 bit) requires 6 separate BMP images, or an ICO file.

Your distribution package is going to have to contain all of these files to be platform independent.

I've not worked with the other platforms, but on Windows, you can change the program icon by right clicking on the existing icon and left clicking on Properties. Left click on the Shortcut tab, and left click on the Change Icon button. Browse over to the distribution directory, and select the ICO file.

I'm sure it's possible to automate the Windows icon change when you deliver the distribution package. I imagine it's possible on the other platforms.

Naga answered 28/12, 2011 at 18:31 Comment(0)
K
2

There's the PE/COFF 4J project which seems to be able to do what you want. It is licensed under the Common Public License (CPL).

Some notes on that:

  • The author seems to be the same as for WinRunJ. This project actually has a PE resource editor in it, called RCEDIT.exe, but it uses native windows calls as you point out yourself. Why the author didn't use his own project (PE/COFF 4J) to accomplish this beats me. It gives me some concern that perhaps the PE/COFF 4J project is abandoned.

  • The documentation page for PE/COFF 4J only mentions that the project is able to parse a PE file but as file as I can tell you can parse, then change something (e.g. an icon resource) and then write the image back to disk.

Like you I've also been searching for a pure Java solution that could manipulate resources in an .EXE (PE file) and have come up empty handed. This is the best bet so far.

Replacing an icon resource in an .EXE file is rather simple when using the native Win32 calls. When doing it from pure Java you have to make bloody sure that the PE file is consistent when you write it back to disk. I haven't scrutinized the PE file format in depth but I suppose that many references will change when replacing/adding a resource, not just the one related to the resource you're replacing/adding.

Khosrow answered 18/2, 2014 at 16:2 Comment(1)
Thanks. No longer working on NetBeans, but I mentioned this project in the NetBeans RFE. (Not accepting this answer yet only because I have not verified that it really works for this purpose.)Giraffe
S
2

This is very long overdue, but we just released an open-source Maven plugin that can do this since we had the same problem.

Disclaimer: I am the author of this project

The documentation for this is available at:

https://zephyr.sunshower.io/site/

Hope this helps for folks who stumble across this as I did.

Sherrill answered 7/7, 2020 at 22:51 Comment(1)
The LinuxWindowsExecutableFileIconService calls out to wine and rcedit.exe. That seems to imply it's not pure Java implementation for updating Windows Portable Executable files.Ecotone
C
1

It looks like the eclipse project has written a small java application to replace the icons.

IconExe from the eclipse project

The app.exe and app64.exe in Netbeans seem to have the follow icons in the resource section:
48 x 48 32bit
32 x 31 32bit
48 x 48 8bit
31 x 31 8bit
16 x 16 8bit

I'm guessing the 32 x 31 is a mistake

Centrifuge answered 1/7, 2014 at 21:6 Comment(1)
Probably a good starting point, though it takes ICO input, so you would first have to convert a PNG input somehow.Giraffe
T
0

You simply have to replace the first ICO or BMP in the executables resource section. That one is automatically picked by explorer as the icon to display.

Timm answered 28/12, 2011 at 19:7 Comment(1)
Right, replacing the icon in the executables resource section is what I want to accomplish. But the question was how to do this, concretely, from a Java-based build possibly running on another OS (possibly on a CI server).Giraffe

© 2022 - 2024 — McMap. All rights reserved.