You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

动态加载程序集时嵌入资源加载问题:WPF加载DLL内图标失败

解决WPF动态加载类库中嵌入图标失败的问题

我之前在做WPF动态加载类库资源的时候踩过一模一样的坑,给你梳理几个关键的排查点和解决办法:

1. 先确认资源的生成操作设置

这是最容易忽略的第一步:

  • 右键类库项目里的.ico文件,打开属性面板
  • 确保生成操作设置为 Resource(如果用pack URI加载),如果是用程序集流读取则设为嵌入的资源
  • 不要设为“内容”或者“无”,否则资源不会被打包到DLL里

2. 修正pack URI的格式错误

你当前用的URI很可能存在两个常见错误:

  • 混淆了程序集名称和命名空间:pack URI里的NamespaceOfMyDll应该是你的类库DLL的程序集名称(比如你的DLL叫MyIconLibrary.dll,这里就写MyIconLibrary),而不是代码的命名空间
  • 路径匹配问题:确保Resources/embeddedresource.ico和你类库项目里的文件路径完全一致,包括文件夹嵌套、文件名大小写(虽然Windows不敏感,但pack URI偶尔会严格区分)

正确的pack URI格式应该是:

pack://application:,,,/YourDllAssemblyName;Component/Resources/embeddedresource.ico

3. 针对动态侧加载的特殊处理

因为你的DLL是动态加载(不是主应用直接引用的),pack://application:,,,/默认指向主应用的程序集,所以可能找不到动态加载的DLL资源。这里有两个可靠的解决方式:

方式一:用加载的程序集构造pack URI

先获取动态加载的DLL的Assembly对象,再构造对应的URI:

// 假设你是通过路径加载DLL,替换成你实际的加载方式
var dllAssembly = Assembly.LoadFrom("Path/To/Your/Library.dll");
var resourceUri = new Uri($"pack://application:,,,/{dllAssembly.GetName().Name};Component/Resources/embeddedresource.ico");

var logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = resourceUri;
logo.CreateOptions = BitmapCreateOptions.IgnoreImageCache; // 避免缓存旧资源
logo.EndInit();

方式二:直接从程序集读取资源流

如果pack URI还是不好用,直接用程序集的资源流加载更稳妥:

var dllAssembly = Assembly.LoadFrom("Path/To/Your/Library.dll");
// 资源路径格式:[类库根命名空间].[文件夹路径].[文件名],用点分隔
var resourcePath = "YourLibraryRootNamespace.Resources.embeddedresource.ico";

using (var stream = dllAssembly.GetManifestResourceStream(resourcePath))
{
    if (stream == null)
    {
        // 资源不存在,这里可以加错误处理
        return;
    }

    var logo = new BitmapImage();
    logo.BeginInit();
    logo.StreamSource = stream;
    logo.CacheOption = BitmapCacheOption.OnLoad; // 必须加,否则流关闭后图片会失效
    logo.EndInit();
    // 将logo赋值给按钮的Icon或Content
    yourButton.Icon = logo;
}

小技巧:可以用dllAssembly.GetManifestResourceNames()输出所有嵌入的资源名称,对照确认你的resourcePath是否正确。

4. 代码里的关键细节

  • StreamSource加载时,必须设置BitmapCacheOption.OnLoad,否则当流被释放后,图片会无法显示
  • UriSource时,加上BitmapCreateOptions.IgnoreImageCache可以避免缓存导致的旧资源问题

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

火山引擎 最新活动