Windows Icon Library¶
ADARE drives a target machine by matching reference icons on-screen and clicking
them. Historically those references were loose PNGs shipped inside each
experiment (<experiment>/img/*.png). That has two problems:
Redistribution. Windows system and application icons are Microsoft’s copyrighted assets, so bundling them in experiments/repositories is legally questionable.
Version drift. The same icon lives at a different DLL/index across Windows versions, so a hand-picked PNG breaks across a fleet.
The icon library solves both. A playbook refers to an icon by a
friendly name (for example windows_explorer); ADARE extracts the
version-correct icon from the target machine at runtime, caches it, and
feeds it to the existing image matcher. No Microsoft bitmaps are ever shipped —
only code plus a small, version-independent name → resolver spec map.
Quick start¶
There are two ways to use an icon-library name. Both accept any term from the registry (see Discovering available names).
1. As a click/drag target (target.icon) — works in every action that
takes a target:
actions:
- click:
target:
icon: windows_explorer
- click:
target:
icon: recycle_bin
strategy: !TopLeft
2. As a visual test (icon=) — works in visual.exists,
visual.not_exists, visual.count_equals, visual.count_min and
visual.count_max:
tests:
- name: recycle_bin_visible
function: visual.exists
parameter:
icon: recycle_bin
That is the whole authoring experience — a name instead of a PNG path. Icons
are otherwise matched exactly like image: targets, so strategies
(!BestConfidence, !TopLeft, …) and everything else behave identically.
Discovering available names¶
List every term shipped in the registry together with the strategy used to resolve it:
$ adare icons list
The registry ships ~100 names covering shell/stock icons (folder,
recycle_bin, drive_fixed, shield …), Windows executables
(windows_explorer, notepad, control_panel …), third-party apps
(chrome, firefox, msedge …), and file-type associations
(pdf_file, docx_file, zip_archive …).
If you request a name that does not exist, the error suggests the closest
matches, so a typo like recycl_bin points you at recycle_bin.
How it works¶
name ──► resolver spec ──► target's own Win32 APIs ──► 256px PNG ──► cache ──► find_icon
(windows_explorer) ({exe: explorer.exe}) (ExtractIconEx) (extracted on target)
The name is looked up in
icon-library.ymlto get a resolver spec (version-independent).On a cache miss, ADARE asks the target’s
adarevmagent to resolve the spec through documented Windows shell APIs and return the largest icon variant as a PNG. Windows itself picks the version-correct DLL/index — ADARE maintains no per-version icon table.The PNG is written to the local cache and matched by the existing CV
find_iconcascade (template → SIFT → ORB), which is already scale-invariant.On a cache hit, the cached PNG is reused with no round-trip to the target.
The cache lives under the ADARE app-data directory, keyed by target OS so an OS upgrade re-extracts instead of reusing a stale bitmap:
<appdata>/icons/<os_key>/<name>.png # e.g. ~/.adare/icons/windows11/recycle_bin.png
Resolver strategies¶
Each registry entry uses exactly one strategy. You rarely need to know these to use a name, but they matter when Adding a new icon.
Strategy |
Example spec |
Windows call |
|---|---|---|
|
|
|
|
|
Icon 0 of an executable ( |
|
|
|
|
|
|
|
|
Explicit fallback — only for the rare icon with no stock ID and no owning executable |
Adding a new icon¶
Add a line to adare/appdata/icon-library.yml under icons: with a
lowercase, snake_case name and a single-strategy spec:
icons:
my_app: {app: myapp.exe}
config_file: {fileassoc: .ini}
folder: {stock: SIID_FOLDER}
Prefer, in order: stock (most version-stable) → exe / app /
fileassoc → dll (last resort). No code change is required; the same name
resolves correctly on every Windows version because the target does the
resolution.
Verifying coverage (debug dump)¶
Against a connected target you can resolve every registry term at once and produce PNGs plus an HTML contact sheet — handy for eyeballing coverage and confirming version-independence across Win10/Win11:
$ adare icons dump-all --host <target-ip> --os-key windows11
...
Dumped 101/103 icons for os_key='windows11'
Contact sheet: ~/.adare/icons/windows11/index.html
Open index.html to see each name, its rendered icon, its resolver spec, and
success/failure. Use --force to re-extract even when cached. Running the
same command against a Win10 target writes to a separate windows10 cache
directory with no code change.
Requirements & caveats¶
Windows targets only. Extraction uses Win32 shell APIs. The
fileassoc/appstrategies additionally depend on the relevant association orApp Pathsentry existing on that machine (e.g.chromeresolves only if Chrome is installed).Agent mode. Extraction goes over the
adarevmWebSocket agent, so the agent must be running on the target. (Pure host-mode/QGA runs do not extract icons.)First use hits the target. The first reference of a name extracts and caches it; subsequent runs are served from cache. Delete the cache directory (or use
--forcewithdump-all) to force re-extraction.Installation.
icon-library.ymlships inappdata/and is installed alongside the OS profiles; when running from a source checkout it is picked up automatically.
See also¶
CLI Reference — the
adare iconscommandsCV Server — the matcher the resolved PNG flows into