繁体   English   中英

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

[英]How to check if a read-only file exists

我正在寻找一种方法来检查只读文件是否存在而无需打开它。 我试过了:

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

但它返回“不存在”。 我正在寻找一种可以检查此类文件是否存在的解决方案。

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 上的文件系统重定向器

如果在 Windows 中,则 function GetFileAttributes返回属性,如果文件存在而没有打开。 出错时,它返回 INVALID_FILE_ATTRIBUTES,然后您可以使用 GetLastError() 检查。

如果您正在检查以便稍后打开它,这可能会导致竞争条件(如前所述的TOCTOU 错误)。

除此之外,确实有理由在不打算打开文件的情况下检查文件是否存在,例如安装程序查看要替换的文件是否存在并警告用户。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM