ipaleka
ipaleka

Reputation: 3957

How to retrieve an icon/image from the window of a running UWP application?

I am able to get icons from non-UWP apps with the following code:

from win32con GCL_HICON, WM_GETICON,
from win32gui import GetClassLong, SendMessageTimeout

_, icon_handle = SendMessageTimeout(hwnd, WM_GETICON, 1, 0, 0, 50)
if icon_handle == 0:
    icon_handle = GetClassLong(hwnd, GCL_HICON)
    if icon_handle == 0:
        return Settings.BLANK_ICON

Documentation says that the next step should be using LoadIcon/LoadImage to extract it from the executable, but I've tried to avoid that.

SO post says UWP app icon path could be retrieved by SHLoadIndirectString (ctypes.windll.shlwapi.SHLoadIndirectString from Python), but that topic deals with the files associations found in the registry - an open window isn't the starting point.

How can I retrieve that "indirect string" having just a window handle? Or maybe someone knows about some other solution to this problem, I'm interested in any type of icon/image I can get.

EDIT: accepted answer together with this answer reveals a way to solve this with Python and ctypes.

Upvotes: 3

Views: 1295

Answers (1)

Strive Sun
Strive Sun

Reputation: 6289

There is not just one icon for a UWP app, there may be many, to be able to adapt to a specific device, form factors, etc.

As @Simon Mourier said, Most of "modern app" (or Windows Store apps, or apps in the AppX application model) information can be queried from official APIs.(I'm just a porter)

You can start with the GetPackageFullName function (it gets the package full name for the specified process). Once you get a package full name, you can use the Package Query API to get more information.

These API are native one, so they don't have equivalent in the .NET Framework to my knowledge. However, they are accessible from WinRT application somehow (and you can indeed access some of the WinRT APIs from standard .NET Framework apps, but this is kindof hack).

The images contained in these apps are special, because they are defined as resources (assets) keys that can be tweaked using qualifiers to form a final path. This is documented for example here: How to name resources using qualifiers (HTML) and here: Quickstart: Using file or image resources (HTML).

The problem is what you can find depends heavily on the application itself, so it's not super easy to determine what image you can use and I have not found any API for this, so I have coded a sample that gets the highest scale image for a given resource name as an exemple (FindHighestScaleQualifiedImagePath). You can load a WPF BitmapSource (or any other imaging platform resource) from this path.

Samples is included in the link provided. For details, please refer to:

Get Icon from UWP App

Upvotes: 4

Related Questions