fopen_s返回错误码2,系统账户下Win32程序失效x64版本运行正常
根因
- 问题本质是64位Windows系统的32位程序文件系统重定向机制导致的。64位Windows中,32位程序默认访问
C:\Windows\System32目录时,系统会自动将请求重定向到C:\Windows\SysWOW64目录,该目录存储32位系统相关的二进制和配置文件。 - 你写死在代码里的路径是
C:\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\Check\\sample.txt,32位版本运行时实际会尝试读取C:\\Windows\\SysWOW64\\config\\systemprofile\\AppData\\Roaming\\Check\\sample.txt,如果这个路径下不存在对应文件,就会返回错误码2(ENOENT,文件/路径不存在)。 - x64版本程序不会触发该重定向机制,访问
System32就是真实的64位系统目录,因此可以正常找到文件。 - 你提到的“同一程序其他逻辑可在相同目录创建文件”,实际是文件被创建到了
SysWOW64对应的路径下,并非你预期的System32路径,你可以直接访问C:\Windows\SysWOW64\config\systemprofile\AppData\Roaming\路径验证该点。
解决方案
方案1:使用Sysnative虚拟别名(推荐)
32位程序访问64位System32目录时,可以用虚拟别名Sysnative替换路径中的System32,系统会自动指向真实的64位System32目录,不会触发重定向。注意该别名仅对32位程序有效,64位程序无法识别,因此可以加编译期适配:
std::string sFileName; #ifdef _WIN32 #ifndef _WIN64 // 32位程序使用Sysnative别名 sFileName = "C:\\Windows\\Sysnative\\config\\systemprofile\\AppData\\Roaming\\Check\\sample.txt"; #else // 64位程序直接用原路径 sFileName = "C:\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\Check\\sample.txt"; #endif #endif
方案2:临时关闭文件系统重定向
可以调用Windows API Wow64DisableWow64FsRedirection临时关闭重定向,文件操作完成后调用Wow64RevertWow64FsRedirection恢复即可,注意两个API必须配对使用,避免影响其他系统调用的正常执行:
#ifdef _WIN32 #ifndef _WIN64 PVOID oldRedirValue = NULL; // 关闭重定向 Wow64DisableWow64FsRedirection(&oldRedirValue); #endif #endif // 执行文件打开操作 errFopenErrNo = FileOpenFunc(&fp, sFileName, "r"); #ifdef _WIN32 #ifndef _WIN64 // 恢复重定向 Wow64RevertWow64FsRedirection(oldRedirValue); #endif #endif
内容的提问来源于stack exchange,提问作者Shreyak Mysore Shamprasad
相关产品推荐
相关产品推荐

