Search code examples
c++windowsrustuwpicons

How to get the icon of a UWP app in C++/Rust?


I'm looking to get the (main) icon of a UWP/Windows store app in C++ or Rust. (Using Windows APIs)

I have all these IDs available (with Slack for example):

System.AppUserModel.ID
91750D7E.Slack_8she8kybcnzg4!Slack

System.AppUserModel.PackageFamilyName
91750D7E.Slack_8she8kybcnzg4

System.AppUserModel.PackageFullName
91750D7E.Slack_4.33.73.0_x64__8she8kybcnzg4

System.AppUserModel.TileUniqueId
{AFFCE86E-C26B-4855-83E5-CDAB2333488B}

I just want to retrieve a HICON, HBITMAP, png path, whatever. (The endgoal being to convert it in base64)

Can someone point me on the right direction? Maybe a I missed a windows function to do that?

I already tried all these functions from Windows API but none of them seems to work for this usecase:

  • ExtractIconExW
  • ExtractAssociatedIconW
  • SHCreateItemFromParsingName then GetImage on IShellItemImageFactory
  • SHGetFileInfoW

Solution

  • Ok, I found a way to get the logo URI, here's the code in Rust:

    let app_full_name = r"Microsoft.WindowsCalculator_11.2210.0.0_x64__8wekyb3d8bbwe";
    
    let package_manager = PackageManager::new().unwrap();
    let package = package_manager.FindPackageByPackageFullName(&HSTRING::from(app_full_name));
    let logoUri = package.unwrap().Logo().unwrap().AbsoluteUri();
    
    println!("{:?}", logoUri);
    // Ok("file:///C:/Program%20Files/WindowsApps/Microsoft.WindowsCalculator_11.2210.0.0_neutral_split.scale-100_8wekyb3d8bbwe/Assets/CalculatorStoreLogo.scale-100.png")
    

    But it requires admin privilege, which is a bit too much for just getting a file path...

    So if anyone has a solution that doesn't require admin privilege, that would be awesome!


    EDIT: ok, apparently, I just needed to use the FindPackageByUserSecurityIdPackageFullName method instead, with an empty SID:

    let package_manager = PackageManager::new().unwrap();
    let package = package_manager.FindPackageByUserSecurityIdPackageFullName(&HSTRING::from(""), &HSTRING::from(app_full_name));
    let logoUri = package.unwrap().Logo().unwrap().AbsoluteUri();