question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[API Proposal]: Add Extract methods to Icon

See original GitHub issue

Background and motivation

System.Drawing.Icon has methods for creating icons from managed resources and associated native icons. It doesn’t, however, allow you to get all native resource icons, or always specify the size that you require.

The Icon constructors that take a path / stream only support .ico files. They do allow choosing a particular size, but also try to pick a color depth based on the current display settings. Color depth matching is of limited use and these constructors are costly as they manually load the entire file, parsing it to create the “best-fit” icon. The full stream is kept in memory (this is particularly painful if you’re trying to load smaller icons).

System.Drawing.Icon.ExtractAssociatedIcon() has some overlap with these new APIs. It will load the first icon from the file it’s given or fall back on whatever executable the file is associated with. The API used for this doesn’t allow specifying a size. (We could spin our own by calling FindExecutable if we find a need in the future.)

API Proposal

namespace System.Drawing;

public class Icon
{
    // The existing Extract method.
    public static Icon ExtractAssociatedIcon(string! filePath);

    // The following work with .ico files as well as PE files (.exe, .dll, etc.). The id is an index when positive or a resource id when negative.

    // Retrieves the specified icon at the current system icon size setting (large by default).
    public static Icon? ExtractIcon(string! filePath, int id, bool smallIcon = false);

    // Allows retrieving the specified icon at a specific size (say 32x32). Icon sizes are always square.
    public static Icon? ExtractIcon(string! filePath, int id, ushort size);

    // Gets the icon count for the specified file.
    public static int GetIconCount(string! filePath);
}

public static class SystemIcons
{
    // Existing.
    public static unsafe Icon GetStockIcon(StockIconId stockIcon, StockIconOptions options = StockIconOptions.Default);

    // New. When asking for an explicit size (as opposed to just large/small) other options aren't available.
    public static unsafe Icon GetStockIcon(StockIconId stockIcon, ushort size);
}

API Usage

// Get the first icon in regedit.exe at 32x32 size.
using Icon icon = Icon.ExtractIcon("regedit.exe", id: 0, size: 32);

// Get the icon from devenv.exe with the 1200 resource id, at the default large size
using Icon icon = Icon.ExtractIcon("devenv.exe", id: -1200);

Alternative Designs

Could potentially add additional constructors to Icon, but behavior differences between string overloads would probably be confusing. For example, as the entire source file is not copied, resizing via Copy is scaled, instead of reparsed.

Risks

Nothing notable.

Notes

  • This API will scale to the requested size from available sizes. We’ll use SHGetStockIconInfo- I believe it tries to scale down from larger sizes.
  • We will not track the original source or update the copy constructors. When the full data is kept in the other APIs the original data is parsed again to try and find a matching size when using the copy constructors. With Icons loaded through these APIs you’ll just get the current backing bitmap scaled if you change sizes with the copy constructors (as you would with HICON constructed Icons and ExtractAssociatedIcon).

Issue Analytics

  • State:closed
  • Created 6 months ago
  • Reactions:1
  • Comments:24 (22 by maintainers)

github_iconTop GitHub Comments

5reactions
harborsiemcommented, Apr 3, 2023

@JeremyKuhne : Did you think about an information for the possible Icon sizes? The information about the sizes are inside of a MultiIcon file in the iconheader.

// Gets the icon sizes for the specified file.
    public static int[] GetIconSizes(string! filePath);

There is a very old interesting article in codeproject.com for MultiIcons with sources. See MultiIcons. I have done some bugfixes to the library in a Github project

2reactions
JeremyKuhnecommented, Apr 1, 2023

I like this plan. So we don’t need any new PInvokes? Have we migrated System.Drawing to CsWin32 yet?

Just a couple of new ones. We can’t migrate System.Drawing to CsWin32 until the Win32 metadata includes the gdiplusflat header. There is an active issue for it, I haven’t had time to try and get it working myself. There is also an issue with some of the shell APIs technically being platform specific. For our purposes we can use any definition, but there is no way to force pick one for AnyCPU in CsWin32.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using Figma API to extract illustrations and icons
We now have a way to retrieve every image as an SVG, which we output as a string. Editing SVGs for icons. We...
Read more >
Skytale Finance Integration Grant Proposal
ICON Grant Proposal Skytale platform Skytale is a DeFi curated ledger to consolidate on-chain ... We agree that we can extract this information...
Read more >
XML Extract
File Name Size Extracted Date/Time GrantsDBExtract20230813v2.zip 55.7 MB Aug 13, 2023 04:40:18 AM EDT GrantsDBExtract20230814v2.zip 55.7 MB Aug 14, 2023 04:41:06 AM EDT GrantsDBExtract20230815v2.zip 55.8 MB...
Read more >
Add support for symbol packages (.snupkg) to NuGet ...
Create new snowplow events to measure how often NuGet symbol packages ... New API route; Addition to the service index payload; Extraction ......
Read more >
Programmatic Language Features
API. There are two common ways to provide a dynamic language feature in ... Hovers show information about the symbol/object that's below the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found