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

如何让WPF应用从工作目录而非程序目录加载资源?

实现从快捷方式所在目录加载WPF资源

核心思路

默认WPF资源加载逻辑是基于程序集或程序安装目录的,要实现从快捷方式所在目录加载资源,需要两步:获取快捷方式的所在目录,然后动态修改资源的加载路径,避免硬编码绝对路径。


步骤1:获取快捷方式所在目录

默认情况下Environment.CurrentDirectory返回程序安装目录,除非快捷方式手动设置了「起始位置」。如果要自动识别快捷方式路径,可通过COM组件解析.lnk文件:

// 需添加COM引用:Windows Script Host Object Model
using IWshRuntimeLibrary;
using System.IO;

public static string GetShortcutDirectory()
{
    string[] commandLineArgs = Environment.GetCommandLineArgs();
    WshShell shell = new WshShell();

    // 遍历命令行参数,查找启动用的快捷方式文件
    foreach (string arg in commandLineArgs)
    {
        if (arg.EndsWith(".lnk", StringComparison.OrdinalIgnoreCase))
        {
            return Path.GetDirectoryName(arg);
        }
    }

    // 非快捷方式启动时, fallback到程序安装目录
    return AppDomain.CurrentDomain.BaseDirectory;
}

如果允许用户手动设置快捷方式的「起始位置」为快捷方式自身所在目录,可直接用Environment.CurrentDirectory替代上述方法,更简单。


步骤2:动态更新ResourceDictionary中的资源路径

在程序启动时,加载ResourceDictionary并替换所有资源的路径:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    string resourceRoot = GetShortcutDirectory();
    // 加载你的ResourceDictionary文件
    var resourceDict = Application.LoadComponent(
        new Uri("/MyWPFApp;component/Resources/YourResourceDict.xaml", UriKind.Relative)) 
        as ResourceDictionary;

    // 遍历并更新BitmapImage类型资源
    foreach (var key in resourceDict.Keys.Cast<object>().ToList())
    {
        if (resourceDict[key] is BitmapImage bitmap)
        {
            // 提取XAML中定义的相对路径(如"Assets/Images/SomeImage.png")
            string relativePath = bitmap.UriSource.ToString();
            string newAbsolutePath = Path.Combine(resourceRoot, relativePath);
            bitmap.UriSource = new Uri(newAbsolutePath, UriKind.Absolute);
        }
        // 同理处理字体、音频等其他资源
        else if (resourceDict[key] is FontFamily font)
        {
            string relativePath = font.Source;
            string newAbsolutePath = Path.Combine(resourceRoot, relativePath);
            resourceDict[key] = new FontFamily(new Uri(newAbsolutePath, UriKind.Absolute), font.FamilyNames);
        }
    }

    Application.Current.Resources.MergedDictionaries.Add(resourceDict);
}

简化XAML中的资源定义

XAML中只需保留相对于Assets的路径,无需前缀:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <BitmapImage x:Key="SomeKey" UriSource="Assets/Images/SomeImage.png" />
    <!-- 其他资源(字体、音频等)同理 -->
</ResourceDictionary>

替代方案:绑定动态路径

如果不想遍历修改资源,可通过ViewModel绑定动态路径:

1. 定义ViewModel

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class ResourceVM : INotifyPropertyChanged
{
    private string _resourceRoot;
    public string ResourceRoot
    {
        get => _resourceRoot;
        set
        {
            _resourceRoot = value;
            OnPropertyChanged();
        }
    }

    public ResourceVM()
    {
        ResourceRoot = GetShortcutDirectory();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

2. 在App.xaml中绑定

<Application x:Class="MyWPFApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MyWPFApp">
    <Application.DataContext>
        <local:ResourceVM />
    </Application.DataContext>
    <Application.Resources>
        <BitmapImage x:Key="SomeKey" 
                     UriSource="{Binding ResourceRoot, StringFormat={}{0}/Assets/Images/SomeImage.png}" />
    </Application.Resources>
</Application>

注意事项

  • 确保快捷方式所在目录存在Assets文件夹及对应资源文件
  • 添加异常处理:若快捷方式目录无资源,自动 fallback到程序安装目录加载
  • 不同类型资源(如视频、音频)需根据其类型调整路径替换逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:56:00