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

C# WPF开发中如何正确获取系统UWP应用包的Logo图标

UWP应用图标加载失败、程序闪退问题解决方案

问题根因

  • Package.Logo属性返回的是UWP生态专属的ms-resource/ms-appx协议URI,不属于WPF默认支持的本地文件/HTTP URI格式,直接传入BitmapImage构造函数无法解析,会触发路径不存在异常。
  • DisplayInfo.GetLogo()方法返回的是WinRT原生的IRandomAccessStream类型,WPF的BitmapImage仅能识别托管Stream类型,未做流转换直接使用会触发类型不兼容异常;传入new Size(1,1)只会返回1x1像素的占位资源,本身也无法作为正常图标使用。
  • 程序闪退有两个核心诱因:一是桌面程序默认未声明调用PackageManager所需的packageQuery能力,调用相关API时会触发权限异常;二是UWP包按用户上下文隔离注册,以管理员身份运行时程序处于高完整性的系统上下文,无法读取当前标准用户下安装的UWP包数据,枚举过程中抛出的未捕获异常会直接导致程序崩溃。

实现步骤

1. 项目前置配置

  • 右键项目选择「编辑项目文件」,配置目标Windows SDK版本,确保目标平台版本不低于Windows 10 1809(10.0.17763.0),添加如下配置:
<PropertyGroup>
  <TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
  <SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
</PropertyGroup>
  • 给项目添加应用程序清单文件(app.manifest),在清单中添加包查询所需的能力声明:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
  <windowsSettings>
    <packageQuery xmlns="http://schemas.microsoft.com/SMI/2020/WindowsSettings">true</packageQuery>
  </windowsSettings>
</application>
  • 禁止配置程序默认以管理员身份启动,必须在当前登录的标准用户上下文下运行,否则无法正常枚举用户安装的UWP应用。

2. 图标加载核心代码

引入以下必要命名空间:

using System.Diagnostics;
using System.Windows.Media.Imaging;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
using Windows.Storage.Streams;
using System.Security.Principal;
using System.Runtime.InteropServices.WindowsRuntime;

枚举包并加载图标的实现:

string currentUserSid = WindowsIdentity.GetCurrent().User.Value;
PackageManager pm = new PackageManager();
List<Package> packages = new List<Package>(pm.FindPackagesForUserWithPackageTypes(currentUserSid, PackageTypes.Main));
// 过滤无有效入口的包
packages.RemoveAll(p => p.GetAppListEntries().Count == 0);

foreach (Package pkg in packages)
{
    foreach (AppListEntry entry in pkg.GetAppListEntries())
    {
        try
        {
            // 按实际UI需求传入图标尺寸,这里以开始菜单常用的48x48为例
            using IRandomAccessStream rawStream = entry.DisplayInfo.GetLogo(new Windows.Foundation.Size(48, 48));
            // 转换为WPF支持的托管流
            using Stream managedStream = rawStream.AsStreamForRead();
            
            BitmapImage icon = new BitmapImage();
            icon.BeginInit();
            icon.CacheOption = BitmapCacheOption.OnLoad;
            icon.StreamSource = managedStream;
            icon.EndInit();
            icon.Freeze(); // 冻结对象避免跨线程访问异常,同时提升渲染性能
            // 此处将icon绑定到对应UI元素即可
        }
        catch (Exception ex)
        {
            // 部分系统内置预留包无公开有效图标,直接跳过
            Debug.WriteLine($"加载应用{entry.DisplayInfo.DisplayName}图标失败: {ex.Message}");
            continue;
        }
    }
}

3. 注意事项

  • 流转换方法AsStreamForRead()依赖System.Runtime.WindowsRuntime程序集,VS2022中配置完目标Windows平台版本后会自动引入该引用,无需手动添加。
  • 不要传入过小的尺寸参数(如1x1),系统会返回最低分辨率的占位图,显示效果完全不可用,建议根据UI实际渲染尺寸传入对应值,系统会自动适配当前系统缩放比例返回最清晰的图标资源。
  • 所有文件流、WinRT流都要加using释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Yudong Liu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:03:18