This morning, I decided it was long overdue that Way of Rhea get its own icon.
I believe that if you’re building a project in Visual Studio there’s a UI through which you can change your exe’s icon–but I’m not a Visual Studio user. It took me quite a while to figure out how to set an exe’s icon from the command line, so I figured I’d document what I learned here in the hopes of saving someone else some time.
It’s possible to dynamically load and set a window icon via code, but for the icon to show up in the file explorer it actually needs to be baked into the executable. This makes sense–
explorer.exe shouldn’t have to have to run an executable to determine its icon!
The rest of this post will walk you through how to do this. The only Rust specific bit is the syntax by which I pass arguments to the linker.
Table of contents
- Table of contents
- Quick update: Window icons
1. Create an icon
2. Create a resources file
arbitrary_name_here ICON "path\to\your\icon.ico"
3. Compile the resources file
Next, you’ll need to compile your
.rc file. The official way to do this is via
rc.exe is not in the path by default, so you’ll need to find it. Mine is located at
C:\Program Files\ (x86)\Windows Kits\10\bin\10.0.18362.0\x86\rc.exe. It was likely placed there when I installed Visual Studio.
Once you’ve located
rc.exe, you can use it to compile your
.rc file into a
Programmatically determining the path to
rc.exe is, unfortunately, not easy. If you need to do this, here are some options:
- Require the user to provide the path
- Call it from within a Developer Command Prompt where it’s already in the path
- Use LLVM’s implementation
- Use the GNU implementation (if cross compiling from Linux)
- Check out how the Zig compiler finds similar files, and write up something similar for
- Use a library like embed-resource or winres to handle the compilation step for you (I haven’t tried either but they seem convenient, thanks Reddit & Twitter for calling them out!)
4. Link with the compiled resources
Lastly, you need to link with the
.res file when building your executable. How exactly you do this depends on your compiler and linker.
If you’ve used a library to handle the resource compilation step for you, it will likely automate this step as well. If not, here’s how I did it in Rust with unrelated options removed for clarity:
cargo rustc -- -C link-args="resources.res"
Update: This can also be done via
That’s it! If everything has gone well, your executable should display your icon in the file explorer and the task bar.
If things aren’t working correctly, there are third party tools like Resource Hacker that you can use to compare your final executable’s resources to that of an executable with a working icon.
Quick update: Window icons
Window icons and executable icons are set separately.
If you’d like to set a window icon to be equivalent to your executable icon, load the icon with
LoadIconA and the arbitrary name you specified in your resources file. Once it’s loaded, store the result in
hIconSm on your window class.
HICON icon = LoadIconA(hInstance, "arbitrary_name_here"); global_window_class.hIcon = icon; global_window_class.hIconSm = icon;
LoadIconA is defined in
winuser.h (included in
Windows.h) and requires linking with
If the icon doesn’t exist,
LoadIconA will return
NULL and a
GetLastError flag will be set.