工具路径为exe时默认显示exe自身图标

ToolItem新增IsExePath计算属性,ExePathToIconConverter通过Icon.ExtractAssociatedIcon提取exe图标并缓存,卡片模板图标区改为三层优先级:FontAwesome > exe图标 > 首字母
This commit is contained in:
2026-05-10 14:26:55 +08:00
parent f33c89d2c4
commit e126184973
4 changed files with 86 additions and 3 deletions

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
@@ -229,3 +230,53 @@ public class StringToIconCharConverter : IValueConverter
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
/// <summary>
/// string (exe路径) → ImageSource: 提取 .exe 文件自身图标,带缓存
/// </summary>
public class ExePathToIconConverter : IValueConverter
{
private static readonly ConcurrentDictionary<string, ImageSource?> Cache = new();
public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not string path || path.Length == 0)
return null;
if (!path.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
return null;
return Cache.GetOrAdd(path, key =>
{
try
{
if (!File.Exists(key))
return null;
using var icon = System.Drawing.Icon.ExtractAssociatedIcon(key);
if (icon == null)
return null;
using var bitmap = icon.ToBitmap();
using var ms = new MemoryStream();
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = ms;
image.EndInit();
image.Freeze();
return image;
}
catch
{
return null;
}
});
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}