Bob Ippolito (@etrepum) on Haskell, Python, Erlang, JavaScript, etc.

Changing win32 icons from a Mac with Perl


The current build procedure for Talking Panda involves taking two stub applications (Mac OS X, Win2K/XP) and replacing their resources. This is extremely easy for the Mac installer, because it's just a bunch of folders. It's actually so convenient that I use the Mac application bundle to house the majority of resources that the Windows installer uses. Unfortunately, I do have to change one in-exe resource for the Win32 installer: the application's icon.

The Win32 application icons are still created "by hand" using Axialis IconWorkshop, which I highly recommend. It understands the Mac OS X icns format and does everything in a few shortcut keystrokes. Eventually I hope to write a script to generate the Windows icons on the fly with PIL, but I had a bit of trouble trying to find updated specs for the Windows XP additions to the ICO format.

I did some research into the Microsoft Portable Executable File Format, but was unable to find any portable C or Python libraries that could create a new executable using an existing one as a template. py2exe does this, but it uses a non-portable C library. Whenever this happens, I generally turn to Perl. CPAN is pretty good about having modules to read/write various file formats (the only other Perl I've used in the past few years is for reading/writing Excel spreadsheets).

Unsurprisingly, CPAN did indeed have what I needed in a module called Win32::Exe, which has a pretty painless API. And here it is, my most recent Perl monstrosity. It takes 3 arguments, the source executable, the new icon, and the destination executable. If someone wrote an equivalent Python module, I'd love to switch, but this does the job quite nicely for now.


use Win32::Exe;
use strict;
my $exe = Win32::Exe->new(shift());
$exe->update(icon => shift());