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

C# .NET Framework 4.8中File.Exists()的异常行为问题

问题根源:Windows文件系统虚拟化搞的鬼

调试和安装后行为不一致,核心原因是Windows文件系统虚拟化:

  • 调试时程序运行在项目输出目录(非系统保护目录),没有虚拟化干预,File.Exists()能准确返回真实文件状态。
  • 安装后目标目录Program Files (x86)是系统受保护目录,普通权限下的文件读写请求会被Windows偷偷重定向到用户专属的%LOCALAPPDATA%\VirtualStore\Program Files (x86)\eMA\eMA目录。你以为Program Files下没文件,但VirtualStore里早就存在该文件,所以File.Exists()返回true,还能读到内容。

另外你代码里还有两处没必要的冗余:

  • 同步的File.Exists()没必要用Task.Run包裹,纯属于浪费线程资源。
  • 硬编码SpecialFolder.ProgramFilesX86路径不靠谱,万一程序安装路径变更就会出错。
解决步骤

1. 修正路径获取逻辑

别硬编码路径,直接获取程序自身的安装目录:

// 记得引用System.Reflection命名空间
private static string AppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

2. 关闭文件虚拟化(推荐)

给项目添加应用程序清单(app.manifest),设置执行级别并禁用虚拟化:

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
  <security>
    <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
      <!-- 如果程序不需要管理员权限,用asInvoker即可 -->
      <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      <!-- 如果必须写入Program Files,直接设为管理员权限 -->
      <!-- <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> -->
    </requestedPrivileges>
  </security>
</trustInfo>

这样所有文件操作都会直接作用于真实的安装目录,不会再被重定向。

3. 简化冗余的异步代码

同步方法没必要套Task.Run,直接修改:

private static bool CheckIfVersionJSONFileExists()
{
    string fileName = Path.Combine(AppPath, "version.json");
    return File.Exists(fileName);
}

调用的时候直接去掉await即可。

验证方式

打开%LOCALAPPDATA%\VirtualStore\Program Files (x86)\eMA\eMA目录,你会发现这里藏着你读到的version.json文件。按上面的方法修改后,文件就会直接出现在真实的安装目录里了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:20:56