.NET5单文件应用如何正常读取目录下的Json/Txt等格式文件?
核心问题根因
- 从.NET5开始,单文件可执行(Single File Executable)模式下,
AppDomain.CurrentDomain.BaseDirectory的返回行为和.NET Framework场景发生了本质变化:程序运行时会将内置的托管依赖、运行时组件解压到系统临时目录,此时这个属性指向的是临时解压目录,而非你双击的exe文件实际所在的物理目录。 - 默认发布配置下,项目中的
sources\settings.json不会作为外部文件和exe一起输出,也没有被嵌入到单文件内部,程序沿着错误的临时目录路径查找配置文件时,会直接触发文件找不到的IO异常。 - 这类启动阶段的路径解析异常发生在Main入口的自定义代码初始化之前,因此你后续编写的try-catch块根本无法捕获,直接表现为程序双击无响应、无任何错误提示就崩溃。
代码适配修改
- 替换原有的路径拼接逻辑,改用可同时适配单文件、传统.NET Framework双场景的API获取exe所在的真实物理目录,不再直接拼接
AppDomain.CurrentDomain.BaseDirectory:
// 获取入口程序的实际所在目录 var exeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location); // 单文件场景下的路径兜底处理 if (string.IsNullOrEmpty(exeDirectory)) { exeDirectory = AppContext.BaseDirectory; } // 用Path.Combine做路径拼接,避免不同系统的路径分隔符不匹配问题 string configPath = Path.Combine(exeDirectory, @"sources\settings.json"); string jsonResult = File.ReadAllText(configPath); return JsonConvert.DeserializeObject<Settings>(jsonResult);
项目与发布配置修正
- 打开项目对应的
.csproj文件,给配置文件补充单文件发布的专属标记,确保发布后sources\settings.json始终以外部文件的形式和exe同目录输出,不会被强制嵌入到单文件内部:
<ItemGroup> <Content Include="sources\settings.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <!-- 标记该文件不嵌入单文件exe --> <ExcludeFromSingleFile>true</ExcludeFromSingleFile> </Content> </ItemGroup>
其中<ExcludeFromSingleFile>true</ExcludeFromSingleFile>是适配单文件场景的关键配置,避免配置文件被默认打包进exe、导致用户无法在不重新编译的前提下修改配置。
- 发布配置调整:在单文件发布的profile中,将
IncludeAllContentForSelfExtract设置为false,避免本应支持用户手动修改的配置文件被默认打包嵌入到exe内部——这类外部配置本身就不应该成为单文件的组成部分。
内容的提问来源于stack exchange,提问作者fatihyildizhan
相关产品推荐
相关产品推荐

