Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am trying to recursively search for files in the computer using WinAPI: FindFirstFile and FindNextFile

I do not understand why, but my code does not work. on the first run, everything is great - I can see all of the content in the C drive. when I go into the sub-folders, for example C:Program Files (x86), I am getting that all the files inside the folders are just ., while if I'd use the function without recursively-search, with the given path of C:Program Files (x86), I would get a list of all the folders inside.

Here is my code :

#include <Windows.h>
#include <iostream>
#include <string>

void FindFile(std::string directory)
{
std::string tmp = directory + "\*";
WIN32_FIND_DATA file;
HANDLE search_handle=FindFirstFile(tmp.c_str(), &file);
if (search_handle != INVALID_HANDLE_VALUE)
{
    do
    {
        std::wcout << file.cFileName << std::endl;
        directory += "" + std::string(file.cFileName);
        FindFile(directory);
    }while(FindNextFile(search_handle,&file));

    if (GetLastError() != 18) // Error code 18: No more files left
        CloseHandle(search_handle);
}
}

int main()
{
    FindFile("C:");
}

The variable tmp is used to store the wildchar *, while directory is containing the next file to be searched (inside the loop).

What is my error?

Thank you!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
420 views
Welcome To Ask or Share your Answers For Others

1 Answer

Each directory (except the root directory) has two entries (. and ..) at the beginning which you need to skip.

Otherwise, you have an infinite recursion:

  • C:*
  • C:Program Files (x86)*
  • C:Program Files (x86).*
  • C:Program Files (x86)..*
  • C:Program Files (x86)...*

and so on.

(You'll also need to check whether each entry is a file or a directory and only recurse into directories.)

For example:

#include <Windows.h>
#include <iostream>
#include <string>
#include <vector>    

void FindFile(const std::wstring &directory)
{
    std::wstring tmp = directory + L"\*";
    WIN32_FIND_DATAW file;
    HANDLE search_handle = FindFirstFileW(tmp.c_str(), &file);
    if (search_handle != INVALID_HANDLE_VALUE)
    {
        std::vector<std::wstring> directories;

        do
        {
            if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if ((!lstrcmpW(file.cFileName, L".")) || (!lstrcmpW(file.cFileName, L"..")))
                    continue;
            }

            tmp = directory + L"" + std::wstring(file.cFileName);
            std::wcout << tmp << std::endl;

            if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                directories.push_back(tmp);
        }
        while (FindNextFileW(search_handle, &file));

        FindClose(search_handle);

        for(std::vector<std::wstring>::iterator iter = directories.begin(), end = directories.end(); iter != end; ++iter)
            FindFile(*iter);
    }
}

int main()
{
    FindFile(L"C:");
    return 0;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...