c++windowsfile

filesystem error: cannot increment recursive directory iterator


Disk Partitions Information:
Drive: C:\ (Local Drive) - Total: 119 GB
Drive: D:\ (Local Drive) - Total: 341 GB
Drive: G:\ (Local Drive) - Total: 15 GB

Pick a path: C:\
"C:\\$Recycle.Bin"
"C:\\$Recycle.Bin\\S-1-5-18"
Error: Unable to iterate through the path C:\ (filesystem error: cannot increment recursive directory iterator: Invalid argument)
Permissions for "C:\\":
rwxrwxrwx
terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
  what():  filesystem error: cannot set permissions: Permission denied [C:\] 

And for the D I only got as error "Unable to iterate through the path C:\ (filesystem error: cannot increment recursive directory iterator: Invalid argument)"

My goal is to print all the files in a directory, when I've got this error, I thought that it was something about permissions or whatever, so I tried to force all the permissions, because that's what I used to do in Python, however I feel like in C++ it didn't worked.

void check_permissions(const fs::path& path) {
    fs::perms p = fs::status(path).permissions();

    std::cout << "Permissions for " << path << ":\n";
    std::cout << ((p & fs::perms::owner_read) != fs::perms::none ? "r" : "-")
              << ((p & fs::perms::owner_write) != fs::perms::none ? "w" : "-")
              << ((p & fs::perms::owner_exec) != fs::perms::none ? "x" : "-")
              << ((p & fs::perms::group_read) != fs::perms::none ? "r" : "-")
              << ((p & fs::perms::group_write) != fs::perms::none ? "w" : "-")
              << ((p & fs::perms::group_exec) != fs::perms::none ? "x" : "-")
              << ((p & fs::perms::others_read) != fs::perms::none ? "r" : "-")
              << ((p & fs::perms::others_write) != fs::perms::none ? "w" : "-")
              << ((p & fs::perms::others_exec) != fs::perms::none ? "x" : "-")
              << '\n';
}
void set_permissions(const fs::path& path, fs::perms permissions) {
    fs::permissions(path, permissions);
}

And below is the function that prints all the files:

void list_files_recursively(const std::string& path) {
    try {
        for (fs::directory_entry entry : fs::recursive_directory_iterator(path)) {
            try {
                std::cout << entry.path() << std::endl;
            } catch (const fs::filesystem_error& e) {
                std::cerr << "Error accessing: " << entry.path() << " (" << e.what() << ")\n";
            }
        }
    } catch (const fs::filesystem_error& e) {
        std::cerr << "Error: Unable to iterate through the path " << path << " (" << e.what() << ")\n";
    }
}

With Google drive G:, it works without a single problem, and I also tried to skip the files that I didn't have access to, it doesn't work.

minimal reproducible example

#include <iostream>
#include <filesystem>
#include <windows.h>

namespace fs = std::filesystem; 

void print_files(const std::string& path) {
    try {
        for (const auto& entry : fs::recursive_directory_iterator(path, fs::directory_options::skip_permission_denied)) {
            try {
                std::cout << entry.path() << std::endl;
            } catch (const fs::filesystem_error& e) {
                std::cerr << "Error accessing: " << entry.path() << " (" << e.what() << ")\n";
            }
        }
    } catch (const fs::filesystem_error& e) {
        std::cerr << "Error: Unable to iterate through the path " << path << " (" << e.what() << ")\n";
    }
}

int main() {
    std::string path;
    std::cout << "Pick a path: ";
    std::cin >> path;

    print_files(path);

    return 0;
}

It returns the same error.

With the other StackOverflow page I wrote this. It doesn't work with C:\\ but it works with specific folders but not with C:\\.

void print_files(const std::string& path) {
    try {
        for (const auto& entry : fs::recursive_directory_iterator(path, fs::directory_options::skip_permission_denied)) {
            try {
                // Skip system and hidden files
                if ((entry.status().permissions() & fs::perms::others_read) == fs::perms::none) {
                    continue;
                }

                std::cout << "Path: " << entry.path()
                          << " | Type: " << (entry.is_directory() ? "Directory" : "File")
                          << " | Size: " << (entry.is_regular_file() ? std::to_string(entry.file_size()) + " bytes" : "N/A")
                          << std::endl;
            } catch (const fs::filesystem_error& e) {
                std::cerr << "Error accessing: " << entry.path() << " (" << e.what() << ")\n";
            }
        }
    } catch (const fs::filesystem_error& e) {
        std::cerr << "Error: Unable to iterate through the path " << path << " (" << e.what() << ")\n";
    }
}

int main() {
    std::string path;
    std::cout << "Pick a path: ";
    std::cin >> path;

    if (!fs::exists(path)) {
        std::cerr << "Error: Path does not exist.\n";
        return 1;
    }

    print_files(path);

    return 0;
}

// BUT THIS STILL DOESN'T WORK WITH C:\ 

Solution

  • As @PaulMcKenzie said, this error is easily avoided by running Visual Studio Code as an administrator

    To run it as an administrator, you can double click Visual Studio Code and scroll down on the options until you find Run as administrator.

    Or, to run it as an administrator all of the time, you can:

    1. Double click on your Visual Studio Code file icon
    2. Scroll down to properties
    3. Settings
    4. On the bottom-right corner, you have "Advanced" settings; click there and check the checkbox that makes it run the application as an Administrator
    5. Press the “OK case”, next to the "Advanced settings case" to close the properties, and now it's good

    From then on, it will run as an administrator everytime you open the application.