如何通过编程获取Windows 10/Microsoft Store应用图标?
获取Windows 10微软商店应用图标的VB.NET实现方案
方法一:通过Shell API直接提取图标(推荐)
微软商店应用在系统中以Shell项形式存在,利用IShellItemImageFactory接口可直接从AUMID或应用对应Shell路径获取图标,这是系统原生支持的方式,兼容性最优。
VB.NET代码示例
Imports System.Runtime.InteropServices Imports System.Drawing Public Class ModernAppIconExtractor ' 定义COM接口 <ComImport> <Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")> <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> Private Interface IShellItemImageFactory Sub GetImage(ByVal size As Size, ByVal flags As UInt32, ByRef hBitmap As IntPtr) End Sub <ComImport> <Guid("42f85136-db7e-439c-85f1-e4075d135fc8")> <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> Private Interface IShellItem Sub BindToHandler(ByVal pbc As IntPtr, ByVal bhid As Guid, ByVal riid As Guid, ByRef ppv As IntPtr) Sub GetParent(ByRef ppsi As IShellItem) Sub GetDisplayName(ByVal sigdnName As UInt32, ByRef ppszName As IntPtr) Sub GetAttributes(ByVal sfgaoMask As UInt32, ByRef psfgaoAttribs As UInt32) Sub Compare(ByVal psi As IShellItem, ByVal hint As UInt32, ByRef piOrder As Int32) End Interface <DllImport("shell32.dll", CharSet:=CharSet.Unicode, PreserveSig:=False)> Private Shared Function SHCreateItemFromParsingName( ByVal pszPath As String, ByVal pbc As IntPtr, ByVal riid As Guid, <MarshalAs(UnmanagedType.Interface)> ByRef ppv As IShellItem) As Integer End Function ' 图标获取参数常量 Private Const SIGDN_DESKTOPABSOLUTEPARSING As UInt32 = &H80028000UI Private Const SIIGBF_BIGGERSIZEOK As UInt32 = &H2 Public Shared Function GetAppIconFromAUMID(aumid As String, iconSize As Size) As Bitmap Dim shellItem As IShellItem = Nothing Try ' 从AUMID创建ShellItem SHCreateItemFromParsingName($"shell:AppsFolder\{aumid}", IntPtr.Zero, GetType(IShellItem).GUID, shellItem) If shellItem Is Nothing Then Return Nothing Dim imageFactory As IShellItemImageFactory = CType(shellItem, IShellItemImageFactory) Dim hBitmap As IntPtr = IntPtr.Zero imageFactory.GetImage(iconSize, SIIGBF_BIGGERSIZEOK, hBitmap) If hBitmap <> IntPtr.Zero Then Dim bmp As Bitmap = Bitmap.FromHbitmap(hBitmap) ' 释放GDI资源 DeleteObject(hBitmap) Return bmp End If Catch ex As Exception ' 处理AUMID无效等异常 Console.WriteLine(ex.Message) Finally If shellItem IsNot Nothing Then Marshal.ReleaseComObject(shellItem) End If End Try Return Nothing End Function <DllImport("gdi32.dll")> Private Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean End Function End Class ' 使用示例 ' Dim iconBitmap As Bitmap = ModernAppIconExtractor.GetAppIconFromAUMID("{6D809377-6AF0-444B-8957-A3773F02200E}\7-Zip\7zFM.exe", New Size(32, 32)) ' If iconBitmap IsNot Nothing Then ' previewButton.Image = iconBitmap ' End If
方法二:通过PackageManager获取图标文件路径
微软商店应用以Appx包形式部署,可通过PackageManager获取应用包的图标资源路径,再从路径提取图标。
VB.NET代码示例
Imports Windows.Management.Deployment Imports Windows.ApplicationModel Imports System.IO Public Class PackageIconExtractor Public Shared Function GetAppIconPathFromAUMID(aumid As String) As String Dim packageManager As New PackageManager() ' 拆分AUMID获取包家族名和应用ID Dim aumidParts As String() = aumid.Split("\") If aumidParts.Length < 2 Then Return Nothing Dim packageFamilyName As String = aumidParts(0) ' 获取匹配的包 Dim packages = packageManager.FindPackagesForUser("", packageFamilyName) If packages.Count = 0 Then Return Nothing Dim targetPackage = packages.FirstOrDefault() If targetPackage Is Nothing Then Return Nothing ' 获取应用清单中的图标 Dim appList = targetPackage.GetAppListEntries() If appList.Count = 0 Then Return Nothing Dim appEntry = appList.FirstOrDefault(Function(e) e.AppUserModelId = aumid) If appEntry Is Nothing Then Return Nothing Dim logo = appEntry.DisplayInfo.Logo ' 拼接完整路径 Dim iconPath = Path.Combine(targetPackage.InstalledLocation.Path, logo.RelativePath) Return If(File.Exists(iconPath), iconPath, Nothing) End Function ' 使用示例:获取路径后提取图标 ' Dim iconPath As String = PackageIconExtractor.GetAppIconPathFromAUMID("{6D809377-6AF0-444B-8957-A3773F02200E}\7-Zip\7zFM.exe") ' If iconPath IsNot Nothing Then ' previewButton.Image = Bitmap.FromFile(iconPath) ' End If End Class
注意事项
- 方法一无需额外权限,直接通过Shell API获取,支持多尺寸图标,是优先选择的方案。
- 方法二需要应用具备
packageQuery权限(UWP项目需配置),桌面应用可能需管理员权限才能访问部分包信息。 - 图标使用完毕后需调用
Dispose()方法释放资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者John Michael Wilkinson
相关产品推荐
相关产品推荐

