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

WPF Resource Dictionaries在ActiveX调用场景下路径加载异常求助

WPF通过Teststand启动时资源字典加载异常解决方案

问题背景

项目中WPF窗口资源字典配置如下:

<Window.Resources>
    <ResourceDictionary x:Name="ResDic">
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary x:Name="dictionary" Source="pack://application:,,,/ProductSelect;component/Loc/ProductSelect.en-US.xaml" ></ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

程序运行表现:

  • Visual Studio调试启动、直接从exe目录双击运行均正常
  • 通过Teststand以ActiveX exe形式启动时,InitializeComponent()方法抛出异常,触发点为上述资源字典的Source属性,异常信息为:
System.IO.IOException: Cannot locate resource 'loc/productselect.en-us.xaml' 

根因说明

Teststand启动exe时,会将自身安装目录作为进程工作目录检索资源,而非使用exe本身所在目录。FusionLog日志显示所有资源检索路径均指向Teststand安装目录:

LOG: Attempting download of new URL file:///C:/Program Files (x86)/National Instruments/TestStand 2013/BIN/ProductSelect.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/National Instruments/TestStand 2013/BIN/ProductSelect/ProductSelect.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/National Instruments/TestStand 2013/BIN/ProductSelect.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/National Instruments/TestStand 2013/BIN/ProductSelect/ProductSelect.EXE.

相关截图:
Teststand报错截图
项目结构截图

可行解决方案

方案1:启动时修正进程工作目录(最推荐)

在窗口构造函数的InitializeComponent()执行之前,或者App.xaml.cs的OnStartup事件中,手动将进程工作目录修改为exe自身所在目录:

using System.IO;
using System.Reflection;

// 该代码需在InitializeComponent()之前执行
string exePath = Assembly.GetExecutingAssembly().Location;
string exeDir = Path.GetDirectoryName(exePath);
Directory.SetCurrentDirectory(exeDir);

该方案侵入性最低,无需修改原有XAML资源配置,直接修复工作目录后WPF默认的pack URI检索逻辑即可正常工作

方案2:简化pack URI写法

如果资源字典存放在当前启动exe的程序集中,可以将原有带程序集名的pack URI简化,避免跨程序集检索的路径依赖:
原写法:

Source="pack://application:,,,/ProductSelect;component/Loc/ProductSelect.en-US.xaml"

修改为:

Source="pack://application:,,,/Loc/ProductSelect.en-US.xaml"

方案3:后台代码动态加载资源字典

不在XAML中硬编码资源字典的Source属性,改为在后台代码中动态加载,完全控制资源加载逻辑:

using System.Reflection;
using System.Windows;

// InitializeComponent()执行后添加以下代码
var resDict = new ResourceDictionary();
string asmName = Assembly.GetExecutingAssembly().GetName().Name;
resDict.Source = new Uri($"pack://application:,,,/{asmName};component/Loc/ProductSelect.en-US.xaml", UriKind.Absolute);
this.Resources.MergedDictionaries.Add(resDict);

该方案不受第三方启动器修改工作目录的影响,资源加载逻辑最可控

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:00:00