简体   繁体   English

WinAPI 文件存在 Function 实现

[英]WinAPI FileExists Function Implemetation

I am coding a simple replacement for std::filesystem::exists() function using Windows API.我正在使用 Windows API 编写std::filesystem::exists() function 的简单替换代码。 Surprisingly, it turned out to be pretty hard.令人惊讶的是,这变得非常困难。 I want to keep my code simple, so I am using minimum functions.我想保持我的代码简单,所以我使用最少的功能。 My function of choice is GetFileAttributesW() .我选择的 function 是GetFileAttributesW() Code is tested with fs::recursive_directory_iterator() function.使用fs::recursive_directory_iterator() function 测试代码。 My function thinks that all files in “C:\Windows\servicing\LCU*” don't exist (ERROR_PATH_NOT_FOUND).我的 function 认为“C:\Windows\servicing\LCU*”中的所有文件都不存在(ERROR_PATH_NOT_FOUND)。 This directory is responsible for storing Windows Update Caches and is famous for having extremely long file names.该目录负责存储 Windows 更新缓存,并以文件名极长而闻名。 I couldn't find anything else about this directory.我找不到有关此目录的任何其他内容。 Example of filenames and my code are included below.文件名示例和我的代码如下所示。 Hope this helps!希望这可以帮助!

Edited: The solution to this problem is to prepend absolute file path with “\\?\” char sequence.编辑:这个问题的解决方案是在绝对文件路径前加上“\\?\”字符序列。 It makes Windows handle short files correctly!它使 Windows 正确处理短文件!

C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2006.1.7\amd64_microsoft-windows-a..g-whatsnew.appxmain_31bf3856ad364e35_10.0.19041.1741_none_ee5d4a8d060d7653\f\new360videossquare44x44logo.targetsize-16_altform-unplated_contrast-black.png
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2006.1.7\amd64_microsoft-windows-a..g-whatsnew.appxmain_31bf3856ad364e35_10.0.19041.1741_none_ee5d4a8d060d7653\f\new360videossquare44x44logo.targetsize-16_altform-unplated_contrast-white.png
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2006.1.7\amd64_microsoft-windows-a..g-whatsnew.appxmain_31bf3856ad364e35_10.0.19041.1741_none_ee5d4a8d060d7653\f\new360videossquare44x44logo.targetsize-20_altform-unplated_contrast-black.png
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2006.1.7\amd64_microsoft-windows-a..g-whatsnew.appxmain_31bf3856ad364e35_10.0.19041.1741_none_ee5d4a8d060d7653\f\new360videossquare44x44logo.targetsize-20_altform-unplated_contrast-white.png
#include <windows.h>

#include <filesystem>
#include <iostream>
#include <string>

using namespace std;
namespace fs = std::filesystem;

int FileExists(wstring file_path) {
    /* TODO:
         1. Doesn't work with "C:\\Windows\\servicing\\LCU\\*".
         2. Improve error system.
    */

    DWORD attributes = GetFileAttributesW(file_path.c_str());
        
    // Valid attributes => File exists
    if (attributes != INVALID_FILE_ATTRIBUTES) {
        return true;
    }

    DWORD error_code = GetLastError();
    wcout << error_code << ' ' << file_path << '\n';

    // Path related error => File doesn't exist
    if (error_code == ERROR_PATH_NOT_FOUND || error_code == ERROR_INVALID_NAME ||
        error_code == ERROR_FILE_NOT_FOUND || error_code == ERROR_BAD_NETPATH)
    {
        return false;
    }

    // Other errors are logged before if statement
    // File is busy with IO operations, etc.
    return error_code;
}

int main() {

    for (fs::path path : fs::recursive_directory_iterator("C:\\", fs::directory_options::skip_permission_denied)) {
        FileExists(path);
    }

    return 0;
}

The solution to this problem is to prepend absolute file path with “\\?\” char sequence.解决这个问题的方法是在绝对文件路径前加上“\\?\”字符序列。 It makes Windows handle shortened file paths correctly!它使 Windows 正确处理缩短的文件路径!

Common way to check file existanse using WinAPI - use file search API eg使用 WinAPI 检查文件存在的常用方法 - 使用文件搜索 API例如

bool file_exist(const std::wstring& path) noexcept
{
    if( path.empty() )
        return false;
    ::WIN32_FIND_DATAW fdata;
    ::HANDLE handle = ::FindFirstFileW(path.data(), &fdata);
    bool result = handle != INVALID_HANDLE_VALUE;
    if(result) {
        ::FindClose(handle);
    }
    return result;
}

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

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