windows 如何检查只读文件是否存在

nfeuvbwi  于 2023-01-31  发布在  Windows
关注(0)|答案(2)|浏览(240)

我正在寻找一种无需打开只读文件即可检查其是否存在的方法。我已尝试:

if (std::filesystem::exists("C:\\Windows\\System32\\hal.dll")) {
    std::cout << "Exists" << std::endl;
}
else {
    std::cout << "Does not exist" << std::endl;
}

但它返回“不存在”。我正在寻找一个解决方案,可以检查像这些文件的存在。

lo8azlld

lo8azlld1#

std::filesystem::exists()工作正常。但是,您可能没有查询所需的文件。
首先,并非每个人都以C:\Windows安装Windows,因此您应该使用GetWindowsDirectory()SHGetFolderPath(CSIDL_WINDOWS)SHGetKnownFolderPath(FOLDERID_Windows)询问操作系统的实际安装位置,例如:

namespace fs = std::filesystem;

fs::path getWindowsPath() {
    WCHAR szPath[MAX_PATH] = {};
    GetWindowsDirectoryW(szPath, MAX_PATH);
    return szPath;

    // or equivalent...
}

其次,在64位Windows系统上,如果在WOW64模拟器中运行的32位应用程序尝试访问64位%WINDIR%\System32文件夹,默认情况下,访问将被重定向到32位%WINDIR%\SysWOW64文件夹,这可以解释为什么您的exists()检查不起作用。
要在WOW64下运行时访问64位System32文件夹,您必须执行以下操作之一:

  • 使用特殊的SysNative别名,例如:
bool isWow64() {
    #ifdef _WIN64
    return false;
    #else
    BOOL bIsWow64 = FALSE;
    return IsWow64Process(GetCurrentProcess(), &bIsWow64) && bIsWow64;
    #endif
}

fs::path getSystemPath() {
    if (isWow64()) {
        return getWindowsPath() / "SysNative";
    }
    else {
        return getWindowsPath() / "System32";

        /* alternatively:

        WCHAR szPath[MAX_PATH] = {};
        GetSystemDirectoryW(szPath, MAX_PATH);
        return szPath;

        or equivalent...
        */
    }
}

...

if (std::filesystem::exists(getSystemPath() / "hal.dll")) {
    std::cout << "Exists" << std::endl;
}
else {
    std::cout << "Does not exist" << std::endl;
}
fs::path getSystemPath() {
    return getWindowsPath() / "System32";
    // or equivalent ...
}

...

PVOID oldValue = NULL;
if (isWow64()) {
    Wow64DisableWow64FsRedirection(&oldValue);
}

if (std::filesystem::exists(getSystemPath() / "hal.dll")) {
    std::cout << "Exists" << std::endl;
}
else {
    std::cout << "Does not exist" << std::endl;
}

if (isWow64()) {
    Wow64RevertWow64FsRedirection(oldValue);
}

有关详细信息,请参见MSDN上的File System Redirector

qxgroojn

qxgroojn2#

如果在Windows中,函数GetFileAttributes返回文件存在但未打开的属性。出错时,它返回INVALID_FILE_ATTRIBUTES,然后您可以使用GetLastError()进行检查。
如果您正在检查以便稍后打开它,则可能导致争用情况(如前所述TOCTOU bug)。
除此之外,确实有理由检查文件是否存在而不打算打开它,例如安装程序要查看要替换的文件是否存在并警告用户。

相关问题