You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过编程获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 18:35:33