【问题标题】:How to retrieve an icon/image from the window of a running UWP application?如何从正在运行的 UWP 应用程序的窗口中检索图标/图像?
【发布时间】:2025-12-22 00:40:15
【问题描述】:

我可以使用以下代码从非 UWP 应用中获取图标:

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 表示下一步应该使用 LoadIcon/LoadImage 将其从可执行文件中提取出来,但我已尽量避免这种情况。

SO post 表示 UWP 应用程序图标路径可以通过 SHLoadIndirectString(来自 Python 的ctypes.windll.shlwapi.SHLoadIndirectString)检索,但该主题涉及在注册表中找到的文件关联 - 打开的窗口不是起点。

如何检索只有窗口句柄的“间接字符串”?或者也许有人知道这个问题的其他解决方案,我对我能得到的任何类型的图标/图像感兴趣。

编辑:接受的答案与this answer 一起揭示了一种使用 Python 和 ctypes 解决此问题的方法。

【问题讨论】:

  • 类可能没有图标,试试WM_GETICON。
  • 不确定我是否理解你的意思,GetClassLong 会在之后运行 - 如果我使用 win32api.SendMessage(hwnd, WM_GETICON, TYPE, 0) 且 TYPE 是 0,1 或 2 中的任何一个,我仍然会收到 0。

标签: c# python winapi uwp pywin32


【解决方案1】:

UWP 应用程序不仅有一个图标,可能还有很多,以便能够适应特定的设备、外形等。

正如@Simon Mourier 所说,大部分“现代应用”(或Windows Store 应用,或AppX 应用模型中的应用)的信息都可以从官方API 中查询到。(我只是一个搬运工)

您可以从GetPackageFullName 函数开始(它获取指定进程的包全名)。获得包全名后,您可以使用Package Query API 获取更多信息。

这些 API 是本机 API,因此据我所知,它们在 .NET Framework 中没有等效的 API。但是,它们可以从 WinRT 应用程序以某种方式访问​​(您确实可以从标准 .NET Framework 应用程序访问一些 WinRT API,但这是一种 hack)。

这些应用程序中包含的图像是特殊的,因为它们被定义为资源(​​资产)键,可以使用限定符进行调整以形成最终路径。例如,此处记录了此内容:How to name resources using qualifiers (HTML) 和此处:快速入门:Using file or image resources (HTML)

问题是你能找到什么在很大程度上取决于应用程序本身,所以确定你可以使用什么图像并不容易,而且我还没有找到任何 API,所以我编写了一个获得最高比例的示例给定资源名称的图像作为示例 (FindHighestScaleQualifiedImagePath)。您可以从此路径加载 WPF BitmapSource(或任何其他成像平台资源)。

示例包含在提供的链接中。详情请参考:

Get Icon from UWP App

【讨论】:

  • 非常感谢您的回答,在结合其中两个答案和一些谷歌搜索后,我已经开始得到一些结果(ctypes.windll.kernel32.GetPackageFullName 可以从 Python 访问 GetPackageFullName)。当我得到代码时,我会在这里发布。再次感谢!
  • @ipaleka 能帮助你是我的荣幸。
  • 我接受了您的回答,因为它可以解决这个问题。我后来又问了一个问题,得到了a beautifully crafted code作为答案。