C# Visual Studio获取可执行文件路径返回原路径问题咨询
问题成因
Process.GetCurrentProcess().MainModule.FileName本身就不是获取托管程序运行路径的可靠实现,返回VS原始生成路径的常见原因有这几个:
- 拷贝文件时出错:要么误把VS调试用的
[程序名].vshost.exe宿主文件当成主程序拷贝,要么拷贝了指向VS本地输出目录的快捷方式而非实际exe文件。这类文件本身就是为VS调试服务的,运行时会沿用调试环境的程序集加载逻辑,自然不会识别你拷贝后的实际目录。 - 框架版本兼容bug:如果项目开启了「首选32位」编译选项,在64位系统上运行.NET Framework 4.0以前的版本时,
Process类的模块枚举逻辑存在已知缺陷,会直接读取PE文件头里记录的编译时输出路径,不会返回运行时的实际磁盘位置。 - 宿主加载干扰:如果这段代码被放到类库中,后续被非托管宿主(Office插件、IIS进程、第三方启动器)加载,
MainModule会返回宿主进程的路径,一旦宿主路径和你本地VS输出路径重合,就会出现你描述的现象。 - 权限不足触发异常逻辑:如果把exe放到
Program Files、系统盘根目录等受UAC保护的路径运行,且程序没有申请管理员权限,Windows的文件系统虚拟化可能干扰路径读取,返回错误的缓存路径。
正确实现方案
不要用进程模块相关API取程序目录,改用.NET原生的程序集定位接口,准确性和兼容性更高:
using System.Reflection; using System.IO; public ProgramSettings() { // 获取入口程序集所在的物理目录 string exeRoot = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); // 用Path.Combine拼接路径,避免硬编码斜杠带来的跨系统问题 filePath = Path.Combine(exeRoot, "Settings"); // 自动创建目录,避免后续写入配置时报目录不存在的错误 Directory.CreateDirectory(filePath); }
补充说明:
- 如果是ClickOnce部署的程序,不要用上述逻辑,需要改用
ApplicationDeployment.CurrentDeployment.DataDirectory获取程序专属数据目录,这类程序不会直接在exe所在物理目录运行。- 如果是.NET Core/.NET 5+的单文件发布场景,可以直接用
AppContext.BaseDirectory获取运行根目录,避免单文件临时解压逻辑带来的路径偏差。
内容的提问来源于stack exchange,提问作者Courtney Sampson
相关产品推荐
相关产品推荐

