Skip to content

feat(image): read the icon of Windows programs and libraries (.exe, .dll) - #1357

Merged
KnifeLemon merged 2 commits into
mainfrom
feat/exe-format-1188
Nov 10, 2026
Merged

KnifeLemon merged 2 commits into
mainfrom
feat/exe-format-1188

Conversation

@KnifeLemon

@KnifeLemon KnifeLemon commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

What users notice

  • A Windows program or library (.exe, .dll) dropped on Filee opens the images donut and converts to its icon: the one Explorer shows for the file.
    • ICO gives that icon exactly as the program stores it, with every size it has (no size is redrawn from another). A preset that changes the picture or asks for other icon sizes rebuilds the icon from the largest size, as for any picture.
    • PNG (and every other picture target, PDF, SVG tracing, …) uses the largest size.
  • A file without an icon of its own (most DLLs, console tools) says so: "This file has no icon of its own (Windows shows a standard one for it)". A 16-bit, damaged or renamed file says it isn't a Windows program Filee can read. Both are translated into all 22 languages.
  • Programs are never run or loaded, only read: Filee reads the headers and the icon, nothing else, so a 2 GB installer is as quick as a small tool.
  • Programs are converted only when dropped or named. Watch folders skip them (a watched Downloads folder would otherwise turn every installer into a picture, and "Move to originals" would move the installer away), so does a folder given to the command line, and Recent conversions never opens one. Browser drags of .exe stay refused as before.

What changed

  • src/Filee.Engines/Magick/ProgramIcon.cs (new): PE32/PE32+ reader that finds the first RT_GROUP_ICON (the icon Explorer shows) and rebuilds an .ico from its RT_ICON entries, with random-access reads and caps (16 MB per size, 64 MB per icon, 16,384 directory entries).
  • ImageReader / ImageEncoder: exe is a package like LIVP and KRA (read as the ICO inside it, largest size converted). MagickImageConverter: program → ICO copies the icon as it is when the preset leaves the picture alone (ProgramIcon.KeptAsItIs).
  • FormatRegistry: new format exe ("Windows program icon (EXE, DLL)", Image, read only) plus FormatRegistry.Program / IsProgram. FormatFields: graded general, image field.
  • Settings schema 78 (after feat(geo): read OpenStreetMap XML (.osm) into the geospatial formats #1355's 77 for .osm): the images donut learns exe and dll; custom claims stay put.
  • FolderWatcher.ShouldIgnore, Cli.ExpandInputs, HistoryItemViewModel.CanOpen (HomePageViewModel.cs): leave programs out as described above.
  • i18n: error.exe_unreadable, error.exe_no_icon in all 22 files.
  • docs/ENGINES.md: ImageMagick row and an EXE / DLL paragraph.

Tests

  • tests/Filee.Engines.Tests/ProgramIconTests.cs (new): builds 32 and 64-bit programs and a DLL in the test (MZ/PE headers, one .rsrc section, the resource tree), with icons made by ImageMagick (BMP sizes plus a PNG 256 px size). Covers: PNG of the largest size, ICO byte-identical to the embedded icon, other icon sizes rebuilt from the largest, first group taken, a missing size left out, no icon, cut-short / not-a-program / 16-bit / too-short files.
  • tests/Filee.Core.Tests/ProgramFormatTests.cs (new): detection, images donut, schema 77 → 78 migration without taking custom claims. FolderWatcherTests and CliTests gained a program case; FormatFieldsTests count updated.
  • Ran: Filee.Core.Tests (all pass), Filee.Cli.Tests (all pass except Zip_to_iso_converts_archive_contents_without_manual_extraction, which fails the same way on main here: no 7-Zip in a fresh worktree), the Magick/route/tracing/3D/Krita/ICNS slice of Filee.Engines.Tests (only FolderIso632Tests.Archive_to_iso_uses_a_direct_archive_route_without_enabling_unrelated_inputs fails, also on main), and App localization/recent-conversion/toolbar tests.
  • Checked by hand against real files (not committed): explorer.exe, regedit.exe, dotnet.exe, 32-bit notepad.exe give their full icon (8 to 13 sizes) and a 256 px PNG; kernel32.dll and System32\imageres.dll (icons moved to the .mun file on Windows 11) say they have no icon.

Not covered / for the maintainer

  • New installs: the images donut has no ICO slot (front PNG/JPG/WEBP/GIF/PDF/SVG), so there ICO is reached through "Edit pictures" or by adding the ICO preset. Existing libraries (schema 58 layout) have ICO on the front. A small "Programs" donut (ICO, PNG) would put both on the front, at the cost of a new profile and migration; left out for now.
  • .mun, .scr, .cpl, .ocx and 16-bit (NE) programs aren't recognised.
  • Only the first icon group is taken, not every icon a library holds (e.g. all of imageres.dll).
  • macOS and Linux untested by hand; the reader is plain managed code, and the tests run anywhere.

Closes #1188

Also answers #1314 (the same request, filed later); it is left open for the maintainer to close.

🤖 Generated with Claude Code

A dropped .exe or .dll is read as the icon Explorer shows for it: the first
RT_GROUP_ICON of its resources, put back together as an .ico in memory by
Filee's own PE reader (ProgramIcon). Only the headers and the icon are read;
the file is never loaded or run.

- ICO is the icon as the program stores it, every size it has, unless the
  preset changes the picture or asks for other icon sizes; PNG and every other
  picture target use the largest size.
- No icon of its own and unreadable/16-bit/damaged files give translated
  errors (error.exe_no_icon, error.exe_unreadable) in all 22 languages.
- Programs are converted only when dropped or named: watch folders and CLI
  folder inputs skip them, and Recent conversions never opens one.
- Settings schema 77: the images donut learns exe and dll; custom claims stay
  put. (Schema 77 may be renumbered if another change takes it first.)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the feature New features label Nov 10, 2026
#1355 took schema 77 for .osm. The images donut now learns exe and dll in
schema 78; FormatFieldsTests counts include both new formats.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@KnifeLemon
KnifeLemon merged commit f4038aa into main Nov 10, 2026
12 checks passed
@github-actions github-actions Bot mentioned this pull request Nov 10, 2026
1 task done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Format]: .exe

1 participant