Home > database >  How do I programmatically get the icons for WIN10 / MS Store Apps?
How do I programmatically get the icons for WIN10 / MS Store Apps?

Time:10-13

ListView Using My.Resources

I have been googling forever for a way to programmatically get the icons for WIN10 / MS Apps (i.e. Modern Apps)? I already have the AUMIDs (e.g. 7-ZIP FILE MANAGER;shell:appsfolder\{6D809377-6AF0-444B-8957-A3773F02200E}\7-Zip\7zFM.exe) working in my program and also the shell commands (e.g. Apps Folder;shell:AppsFolder). I also have access to the Applications folder, but I can't find a way to get the MS App / Windows Store icons to display on my Preview button? Do you have any ideas? I am using Visual Studio 2019 / VB.NET. My program uses a ListView to display each of the programs/apps/folders and currently extracts icons from executable paths to display on dynamically created buttons and also on a Preview button which can be clicked to run the app/program. But, I can't find a way to do the same thing for WIN10/MS Store Apps? If anyone has any ideas or can even show some code which extracts these icons directly from the system I would greatly appreciate it! I'm sorry I don't have any code to show because I have been looking for many days and can't find any examples!

What I need

In the Applications folder (i.e. virtual), you can create Desktop icons from the MS Apps Icons as follows. But, if the program I'm trying to create depends upon these Desktop shortcuts this seems to be very limited. I really need to find a way to access the native MS Apps icons to display when running each app from my program.

MS Apps Desktop Icons

enter image description here

LIST OF MS APPS WITHOUT ICONS

By "without icons" I mean that I haven't found a way yet to get or extract these icons from the system? The idea of the icons is to visually identify the program or app currently selected in the ListView items on the preview button and also on dynamically created buttons which run the program/app!

MS APPS:

BING WEATHER;"shell:appsfolder\Microsoft.BingWeather_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
CALENDAR;"shell:appsfolder\microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.calendar";Winver___LocalLang_2_MAINICON
CORTANA;"shell:appsfolder\Microsoft.549981C3F5F10_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
MAIL;"shell:appsfolder\microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.mail";Winver___LocalLang_2_MAINICON
MICROSOFTSOLITAIRECOLLECTION;"shell:appsfolder\Microsoft.MicrosoftSolitaireCollection_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
MS 3D VIEWER;"shell:appsfolder\Microsoft.Microsoft3DViewer_8wekyb3d8bbwe!Microsoft.Microsoft3DViewer";Winver___LocalLang_2_MAINICON
MS MAPS;"shell:appsfolder\Microsoft.WindowsMaps_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
MS ONE NOTE;"shell:appsfolder\Microsoft.Office.OneNote_8wekyb3d8bbwe!microsoft.onenoteim";Winver___LocalLang_2_MAINICON
MS TO DO;"shell:appsfolder\Microsoft.Todos_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
MS WORD ONLINE VERSION???;"shell:appsfolder\word.office.com-CECA1A7F_jc2kecmnkxwqc!App";Winver___LocalLang_2_MAINICON
PAINT 3D;shell:appsfolder\Microsoft.MSPaint_8wekyb3d8bbwe!Microsoft.MSPaint;Winver___LocalLang_2_MAINICON
PHOTOSHOP EXPRESS;"shell:appsfolder\AdobeSystemsIncorporated.AdobePhotoshopExpress_mtcwf2zmmt10c!App";Winver___LocalLang_2_MAINICON
WINDOWS CLOCK;"shell:appsfolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
WINDOWS PHOTOS;"shell:appsfolder\Microsoft.Windows.Photos_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
WINDOWS SOUND RECORDER;"shell:appsfolder\Microsoft.WindowsSoundRecorder_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
ZUNE MUSIC;"shell:appsfolder\Microsoft.ZuneMusic_8wekyb3d8bbwe!Microsoft.ZuneMusic";Winver___LocalLang_2_MAINICON
ZUNE VIDEO;"shell:appsfolder\Microsoft.ZuneVideo_8wekyb3d8bbwe!Microsoft.ZuneVideo";Winver___LocalLang_2_MAINICON

OTHERS:

INTELGRAPHICSEXPERIENCE;"shell:appsfolder\AppUp.IntelGraphicsExperience_8j3eq9eme6ctt!App";Winver___LocalLang_2_MAINICON
MS GET HELP;"shell:appsfolder\Microsoft.GetHelp_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
MS GET STARTED TIPS;"shell:appsfolder\Microsoft.Getstarted_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
WINDOWS FEEDBACK HUB;"shell:appsfolder\Microsoft.WindowsFeedbackHub_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
WINDOWS MIXED REALITY PORTAL;"shell:appsfolder\Microsoft.MixedReality.Portal_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON
YOUR PHONE;"shell:appsfolder\Microsoft.YourPhone_8wekyb3d8bbwe!App";Winver___LocalLang_2_MAINICON

My Research

I tried Nirsoft's utility program, IconsExtract Game Fire app showing apps imported from Microsoft Store

I use the PackageManager class part of Windows.Management.Deployment namespace to retrieve information about the installed Microsoft Store apps including their icons.

To use the PackageManager class add reference to Windows.Foundation.UniversalApiContract located at C:\Program Files (x86)\Windows Kits\10\References[SDK Version]\Windows.Foundation.UniversalApiContract[Version]\Windows.Foundation.UniversalApiContract.winmd

Use the following code to enumerate the installed packages and apps:

Imports Windows.Management.Deployment

Module Test

    Public Sub Main()

        Dim pkgMngr As New PackageManager()

        For Each package In pkgMngr.FindPackages()

            Try

                For Each app In package.GetAppListEntries

                    Try

                        Dim pkgVersion = package.Id.Version

                        Console.WriteLine(String.Format("App name: {0}", app.DisplayInfo.DisplayName))
                        Console.WriteLine(String.Format("Package logo file: {0}", package.Logo.OriginalString))
                        Console.WriteLine(String.Format("Package publisher: {0}", package.PublisherDisplayName))
                        Console.WriteLine(String.Format("AppUserModelId: {0}", app.AppUserModelId))
                        Console.WriteLine(String.Format("App description: {0}", app.DisplayInfo.Description))
                        Console.WriteLine(String.Format("Install location: {0}", package.InstalledPath))
                        Console.WriteLine(String.Format("Package version: {0}", New Version(pkgVersion.Major, pkgVersion.Minor, pkgVersion.Build, pkgVersion.Revision).ToString))

                    Catch ex As Exception
                        Console.ForegroundColor = ConsoleColor.Red
                        Console.WriteLine(ex.Message)
                        Console.ResetColor()

                    Finally
                        Console.WriteLine(New String("-"c, 10))

                    End Try

                Next

            Catch ex As Exception
                Console.ForegroundColor = ConsoleColor.Red
                Console.WriteLine(ex.Message)
                Console.ResetColor()
            End Try

        Next

        Console.ReadLine()

    End Sub

End Module

The Package.Logo property will give you the package logo file path, usually a PNG image file. You can load the image easily using the Image.FromFile method.

Here is an extra method to help get the app cover art/wide logo by parsing the app manifest file AppxManifest.xml, just specify the app install path to the GetStoreAppCoverArt method.

The screenshot is for our app Game Fire displaying apps/games imported from Microsoft Store using their cover/wide logos.

Private Function GetStoreAppCoverArt(appInstallDir As String) As String

    Try

        Dim manifestFilePath = Path.Combine(appInstallDir, "AppxManifest.xml")

        If File.Exists(manifestFilePath) Then

            Dim xmlDocAppManifest As XmlDocument = Nothing

            If IsValidXml(manifestFilePath, xmlDocAppManifest) Then

                Dim defaultTitleNode As XmlNode = xmlDocAppManifest.DocumentElement.Item("Applications").Item("Application").Item("uap:VisualElements").Item("uap:DefaultTile")

                If defaultTitleNode IsNot Nothing Then

                    Dim wideLogoValue = defaultTitleNode.Attributes("Wide310x150Logo").Value.Trim

                    Dim logoFileName = Path.GetFileNameWithoutExtension(wideLogoValue)
                    Dim assetsDir = Path.Combine(appInstallDir, Path.GetDirectoryName(wideLogoValue))

                    For Each f In New DirectoryInfo(assetsDir).EnumerateFiles("*.png", SearchOption.TopDirectoryOnly)

                        If f.Name.StartsWith(logoFileName, StringComparison.OrdinalIgnoreCase) Then
                            Return f.FullName
                        End If

                    Next

                Else
                    Throw New XmlException("Application uap:DefaultTile node is missing.")
                End If

            Else
                Throw New XmlException("Application manifest file is invalid.")
            End If

        End If

        Return String.Empty

    Catch ex As Exception
        Return String.Empty
    End Try

End Function

Public Function IsValidXml(filePath As String, ByRef xDoc As XmlDocument) As Boolean

    Try

        If File.Exists(filePath) Then

            Dim errInfo As Exception = Nothing

            Using fs = CreateFileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, errInfo)

                If fs Is Nothing Then Throw errInfo

                Using sr = New StreamReader(fs, Encoding.UTF8, True)
                    Using xReader As XmlReader = XmlReader.Create(sr, New XmlReaderSettings() With {.XmlResolver = Nothing})
                        xDoc = New XmlDocument() With {.XmlResolver = Nothing}
                        xDoc.Load(xReader)
                        Return True
                    End Using
                End Using

            End Using

            Return False

        Else
            Throw New FileNotFoundException("The specifed file does not exit.", filePath)
        End If

    Catch ex As Exception
        Return False
    End Try

End Function

Public Function CreateFileStream(filePah As String, mode As FileMode, access As FileAccess, share As FileShare, Optional ByRef errInfo As Exception = Nothing, Optional retries As Integer = 10) As FileStream

    For i = 0 To retries - 1

        Dim fs As FileStream = Nothing

        Try

            fs = New FileStream(filePah, mode, access, share)
            errInfo = Nothing
            Return fs

        Catch ex As IOException
            errInfo = ex
            If fs IsNot Nothing Then fs.Dispose()
            Thread.Sleep(100)

        Catch ex As Exception
            errInfo = ex
            Return Nothing

        End Try

    Next

    Return Nothing

End Function
  • Related