I'm writing a Python-based launcher that is automatically populated form Windows' Start menu. I plan to extend it to include UWP apps. Listing and launching them isn't hard, but accessing their icons seems to be tricky.
As the apps reside under \program files\windowsapps\
, their icons seem to be inaccessible due to permission issue. I don't plan to run my program elevated.
I have the current leads:
%homepath%\AppData\Local\Microsoft\Windows\Explorer
(errors of displaying their icons can be fixed by removing these cache files), but I didn't find any solutions to read the image data from there.This example will display the icon for an UWP app, by its name. Names can be listed by the powershell command:
Get-AppxPackage | Select-Object -ExpandProperty Name
Microsoft.WindowsCalculator
is used for the example, but I've tried it out with other apps (Terminal, Spotify, Teams, Paint, ZuneMusic, DuckDuckGo, Outlook, WindowsStore etc.) and it worked well : )
Python code:
from pathlib import Path
from subprocess import run
from tkinter import Label, Tk
from PIL import Image, ImageTk
def get_powershell_output(command: str) -> str:
process = run(command, capture_output=True, text=True, shell=True)
return process.stdout.strip()
def get_icon_name(app_name: str) -> Path:
command = f"""powershell "(Get-AppxPackage -Name {app_name} | Get-AppxPackageManifest).package.properties.logo" """
return Path(get_powershell_output(command))
def get_install_path(app_name: str) -> Path:
command = f"""powershell "(Get-AppxPackage -Name {app_name}).InstallLocation" """
return Path(get_powershell_output(command))
def locate_icon(icon: Path, install_path: Path) -> Path:
matches = install_path.glob(f"**/{icon.stem}*.png")
# usually 3 matches (default, black, white), let's use default
return list(matches)[0]
def show_icon(icon_path: Path) -> None:
root = Tk()
root.title("Display Icon")
pil_image = Image.open(icon_path)
tk_image = ImageTk.PhotoImage(pil_image)
label = Label(root, image=tk_image)
label.pack()
root.mainloop()
def main(current_name: str) -> None:
icon_path = get_icon_name(current_name)
print(icon_path)
# Assets\CalculatorStoreLogo.png
install_path = get_install_path(current_name)
print(install_path)
# C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_11.2411.1.0_x64__8wekyb3d8bbwe
selected_icon = locate_icon(icon_path, install_path)
print(selected_icon)
# C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_11.2411.1.0_x64__8wekyb3d8bbwe\Assets\CalculatorStoreLogo.scale-200.png
show_icon(selected_icon)
# see the proof
if __name__ == "__main__":
main("Microsoft.WindowsCalculator")