【问题标题】:WINAPI: File exists check failWINAPI:文件存在检查失败
【发布时间】:2017-06-19 02:44:40
【问题描述】:

我想检查指定位置是否存在某个文件。我为此尝试了多种解决方案,但似乎没有一个能正常工作,因为它们都返回 false。

毫无疑问,该文件存在于指定位置。

可执行文件以管理员身份运行,因此我拥有相应的权限。

我使用的代码:

#include <io.h>
#include <string>
#include <Shlwapi.h>

std::string str = "C:\WINDOWS\System32\iluminated.dll";
unsigned long attrib = GetFileAttributes(str.c_str());

bool exists1 = (attrib != INVALID_FILE_ATTRIBUTES && 
            !(attrib & FILE_ATTRIBUTE_DIRECTORY)) &&
            GetLastError() != ERROR_FILE_NOT_FOUND; // false
bool exists2 = ( _access( str.c_str(), 0 ) != -1 ); // false
bool exists3 = PathFileExists(str.c_str()) != 0; // false

是不是我做错了什么?

【问题讨论】:

  • 您至少没有收到编译器警告吗?比如warning C4129: 'W' : unrecognized character escape sequence?
  • @MichaelWalz 我做到了。然而双斜线使警告消失。
  • 警告通常是错误的。

标签: c++ visual-studio c++11 winapi visual-studio-2012


【解决方案1】:

您应该对路径使用双反斜杠,因为如果您在字符串中使用单反斜杠,它们会被解释为命令符号(例如,\n 行):

"C:\\WINDOWS\\System32\\iluminated.dll"

或者,您可以使用正斜杠,它们适用于大多数操作系统:

"C:/WINDOWS/System32/iluminated.dll"

【讨论】:

  • 哦,不错。谢谢。
  • 顺便说一句。知道如何用 \\ 或 / 替换 GetWindowsDirectory 函数返回的单斜杠吗?
  • @DonaldDuck,类似于path.replace("\","/");
  • \\ 由编译器解释,而不是由您解释。不要修改GetWindowsDirectory() 返回的内容;这已经是正确的了。仅在 C 中构建字符串或字符文字时使用 \\(例如,"...")。当编译器看到 \\ 时,它会吃掉多余的 \ 并在输出中生成一个 \。
  • 或使用原始字符串文字:R"(C:\WINDOWS\System32\iluminated.dll)"。顺便说一句,illuminated 有两个 L,这也可以解释为什么你找不到文件。
【解决方案2】:

我找到了答案。事实证明,在尝试访问 64 位 Windows 时,Windows 总是将system32 重定向到syswow64。我必须使用SysNative 目录,即使它不存在 - Windows 会将其重定向到正确的 system32 目录。

自 Visual Studio 2012 起,应用程序项目默认为“任何 CPU 32 位首选”。如果您在 64 位 Windows 上运行这样的可执行文件 操作系统,然后它将作为 32 位进程启动并被 受 WOW64 文件系统重定向的影响。

当 64 位 Windows 上的 32 位进程尝试访问 “C:\Windows\System32”,WOW64 将其重定向到“C:\Windows\SysWOW64”。 有几种方法可以访问真正的“C:\Windows\System32” 目录:

  • 使用“C:\Windows\SysNative”,即使它没有出现在目录中,WOW64 也会重定向到“C:\Windows\System32” 清单。这是一种简单的方法,不太可能导致问题。
  • 使用 Wow64DisableWow64FsRedirection 和 Wow64RevertWow64FsRedirection。
  • 使用 64 位进程。

来源:https://social.msdn.microsoft.com/Forums/en-US/c54f8368-035e-478e-b988-b180a3c7e3da/file-not-found-for-existing-file-in-system32-directory?forum=csharpgeneral

【讨论】:

  • “任何 CPU 32 位首选” 仅与 .NET 应用程序相关。不过,64 位 Windows 上 32 位进程的规则与本机 (C++) 应用程序相同。
  • 官方文档为File System Redirector:“32位应用程序可以通过将%windir%\Sysnative替换为%windir%\System32来访问本机系统目录。WOW64将Sysnative识别为使用的特殊别名表示文件系统不应该重定向访问。这种机制灵活且易于使用,因此,建议绕过文件系统重定向的机制。注意,64位应用程序不能使用Sysnative别名虚拟目录不是真实目录。"
猜你喜欢
  • 1970-01-01
  • 2018-09-08
  • 2022-10-07
  • 2023-02-17
  • 1970-01-01
  • 2011-07-28
  • 2014-08-24
  • 2014-10-06
  • 1970-01-01
相关资源
最近更新 更多