WPF应用如何将App.config嵌入程序或存储到其他路径实现单文件部署
WPF单文件部署嵌入App.config的可行方案
方案1:.NET Core 3.0+ / .NET 5+ 版本内置支持
直接修改项目的.csproj配置文件,在发布配置节点添加如下属性即可:
<PropertyGroup> <!-- 开启单文件发布 --> <PublishSingleFile>true</PublishSingleFile> <!-- 自动包含所有内容文件到单文件包,包括自动生成的exe.config --> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <SelfContained>true</SelfContained> </PropertyGroup>
发布后生成的单exe会自动把配置文件打包在内,运行时会自动识别加载配置,<probing>节点的程序集探测逻辑可以正常生效,不需要修改任何业务代码。
方案2:.NET Framework 版本手动嵌入配置
如果是基于.NET Framework的WPF项目,可以通过把App.config嵌入程序集的方式实现:
- 右键项目中的
App.config文件,选择「属性」,将「生成操作」修改为「嵌入的资源」 - 在
App.xaml.cs的OnStartup方法中重写配置加载逻辑,手动读取嵌入的配置并生效<probing>规则:
using System.Configuration; using System.Reflection; using System.IO; using System.Runtime.Serialization.Configuration; protected override void OnStartup(StartupEventArgs e) { var assembly = Assembly.GetExecutingAssembly(); // 替换为你的项目默认命名空间 string configResourceName = "你的项目命名空间.App.config"; using (Stream stream = assembly.GetManifestResourceStream(configResourceName)) { if (stream != null) { using (StreamReader reader = new StreamReader(stream)) { string configContent = reader.ReadToEnd(); ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); config.ReadXml(configContent); // 手动生效probing路径 var runtimeSection = config.GetSection("runtime") as RuntimeSection; if (runtimeSection?.AssemblyBinding?.Probing != null) { string privatePath = runtimeSection.AssemblyBinding.Probing.PrivatePath; if (!string.IsNullOrEmpty(privatePath)) { AppDomain.CurrentDomain.AppendPrivatePath(privatePath); } } } } } base.OnStartup(e); }
方案3:全版本通用自定义探测逻辑
如果不需要保留config文件结构,你可以直接把探测路径硬编码到代码中,订阅AssemblyResolve事件自定义程序集加载逻辑,完全不依赖系统的config配置:
protected override void OnStartup(StartupEventArgs e) { AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { // 替换为你自定义的探测路径 string[] probePaths = new[] { "libs", "plugins" }; string assemblyName = new AssemblyName(args.Name).Name + ".dll"; foreach (var path in probePaths) { string fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path, assemblyName); if (File.Exists(fullPath)) { return Assembly.LoadFrom(fullPath); } } return null; }; base.OnStartup(e); }
如果你想要把配置存到其他自定义路径,只需要在程序启动时调用ConfigurationManager.OpenMappedExeConfiguration传入自定义的配置文件路径即可,相关配置规则都可以手动读取处理,不需要依赖默认的main.exe.config文件。
内容的提问来源于stack exchange,提问作者asunax
相关产品推荐
相关产品推荐

