Reputation: 485
How do I correct the piece of code below for it to work properly? The purpose of the function is only to delete directories and files inside of the directory.
Because when I run this function (even in a separate thread), it doesn't delete the folder passed in the first argument due to some handles existing (probably).
And Windows doesn't delete the folder until the end of the program, see code below.
How do I fix existing of handles before the RemoveDirectory is called?
I already tried to move the HANDLE variable (which is inside of the function below) out of stack when RemoveDirectory is called.
The problem is just in the delayed deleting of the folder (not other files, they delete normally).
int DeleteDirectory(const std::string &refcstrRootDirectory,
bool bDeleteSubdirectories = true)
{
bool bSubdirectory = false; // Flag, indicating whether
// subdirectories have been found
HANDLE hFile; // Handle to directory
std::string strFilePath; // Filepath
std::string strPattern; // Pattern
WIN32_FIND_DATA FileInformation; // File information
strPattern = refcstrRootDirectory + "\\*.*";
hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation);
if(hFile != INVALID_HANDLE_VALUE)
{
do
{
if(FileInformation.cFileName[0] != '.')
{
strFilePath.erase();
strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;
if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(bDeleteSubdirectories)
{
// Delete subdirectory
int iRC = DeleteDirectory(strFilePath, bDeleteSubdirectories);
if(iRC)
return iRC;
}
else
bSubdirectory = true;
}
else
{
// Set file attributes
if(::SetFileAttributes(strFilePath.c_str(),
FILE_ATTRIBUTE_NORMAL) == FALSE)
return ::GetLastError();
// Delete file
if(::DeleteFile(strFilePath.c_str()) == FALSE)
return ::GetLastError();
}
}
} while(::FindNextFile(hFile, &FileInformation) == TRUE);
// Close handle
::FindClose(hFile);
DWORD dwError = ::GetLastError();
if(dwError != ERROR_NO_MORE_FILES)
return dwError;
else
{
if(!bSubdirectory)
{
// Set directory attributes
if(::SetFileAttributes(refcstrRootDirectory.c_str(),
FILE_ATTRIBUTE_NORMAL) == FALSE)
return ::GetLastError();
// Delete directory
if(::RemoveDirectory(refcstrRootDirectory.c_str()) == FALSE)
return ::GetLastError();
}
}
}
return 0;
}
p.s. the piece of code was taken from here: How to delete a folder in C++?
Upvotes: 1
Views: 296
Reputation: 485
First of all, I apologize for asking such a misleading question but...
I have found my mistake, It is not in the function that I posted in the question.
I have a project where I used my function DirectoryExists, and there was a function from the header "opendir" (It is a portable version of linux header for Windows and there are probably WINAPI HANDLEs inside of it). And I forgot to close the directory after I've opened it to check if it exists.
bool DirectoryExists(const std::string & path)
{
DIR *dir = opendir(path.c_str());
if (dir) {
return true;
}
else
return false;
}
And I've corrected the error:
bool DirectoryExists(const std::string & path)
{
DIR *dir = opendir(path.c_str());
closedir(dir);
if (dir) {
return true;
}
else
return false;
}
I hope that this question can help someone to understand why RemoveDirectory() could work as not expected. There could be some handles that you did not notice and It's not that clear If you're not a professional Windows programmer.
Upvotes: 1