Warum habe ich Probleme, rekursiv Verzeichnisse löschen?
Ich habe eine Anwendung geschrieben, verwendet die WIN32-api zum erstellen von einem temporär-Verzeichnis-Hierarchie. Nun, wenn Sie wollen löschen Sie die Verzeichnisse, die beim Herunterfahren der Anwendung, die ich laufen in einige Probleme.
So können sagen, ich habe eine directory-Hierarchie: C:\temp\directory\subdirectory\
Ich bin mit dieser rekursiven Funktion:
bool Dir::deleteDirectory(std::string& directoryname, int flags)
{
if(directoryname.at(directoryname.size()-1) != '\\') directoryname += '\\';
if ((flags & CONTENTS) == CONTENTS)
{
WIN32_FIND_DATAA fdata;
HANDLE dhandle;
directoryname += "\\*";
dhandle = FindFirstFileA(directoryname.c_str(), &fdata);
//Loop through all the files in the main directory and delete files & make a list of directories
while(true)
{
if(FindNextFileA(dhandle, &fdata))
{
std::string filename = fdata.cFileName;
if(filename.compare("..") != 0)
{
std::string filelocation = directoryname.substr(0, directoryname.size()-2) + StringManip::reverseSlashes(filename);
//If we've encountered a directory then recall this function for that specific folder.
if(!isDirectory(filelocation)) DeleteFileA(filename.c_str());
else deleteDirectory(filelocation, DIRECTORY_AND_CONTENTS);
}
} else if(GetLastError() == ERROR_NO_MORE_FILES) break;
}
directoryname = directoryname.substr(0, directoryname.size()-2);
}
if ((flags & DIRECTORY) == DIRECTORY)
{
HANDLE DirectoryHandle;
DirectoryHandle = CreateFileA(directoryname.c_str(),
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
bool DeletionResult = (RemoveDirectoryA(directoryname.c_str()) != 0)?true:false;
CloseHandle(DirectoryHandle);
return DeletionResult;
}
return true;
}
Diese Funktion iteriert über das Verzeichnis den Inhalt des temp-Verzeichnis und für jedes Verzeichnis im temp-Verzeichnis behält er erinnert sich, bis es auf der untersten Verzeichnis; ein Unterverzeichnis im Beispiel.
Außerdem gibt es 3 flags definiert
enum DirectoryDeletion
{
CONTENTS = 0x1,
DIRECTORY = 0x2,
DIRECTORY_AND_CONTENTS = (0x1 | 0x2)
};
Wenn Sie mit dieser Funktion, es entfernt nur die niedrigsten Unterverzeichnis, und ich kann nicht entfernen Sie die, die höher in der Hierarchie, weil es sagt, dass das Verzeichnis nicht leer ist. Wenn ich gehen und schauen Sie in das Verzeichnis 'Verzeichnis' ist nur entfernt werden, nachdem die Anwendung beendet. Jedoch, wenn ich versuche, diese Kapseln in eine nicht rekursive einfache main-Anwendung habe ich überhaupt keine Probleme mit dem löschen der Verzeichnisse.
- als ich das gelesen im Betreff, ich dachte, Sie wollten versuchen, löschen win32-Verzeichnis...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bist du nicht schließen dhandle von all diesen
FindFirstFile
nennt, so dass jedes Verzeichnis hat einen Verweis auf es, wenn Sie versuchen, es zu löschen.Und, warum müssen Sie erstellen
DirectoryHandle
? Es ist nicht nötig, und das wird wahrscheinlich auch der block-Verzeichnis löschen.Wenn Ihr die app schließt, diese Griffe sind gezwungen, zu schließen, und (ich denke) der Letzte versucht zu löschen, dann gelingt es.
Gibt es eine Windows-API SHFileOperation, das wird ein rekursiver Ordner löschen für Sie.
SHFileOperations funktioniert Super auf Windows 7. In der Tat In der IFileOperation Dokumentation sagt
IFileOperation kann nur angewendet werden, in einem Singlethread-apartment (STA) situation. Es kann nicht verwendet werden, für einen Multithread-apartment (MTA) situation. Für MTA, müssen Sie noch SHFileOperation verwenden.
Aber mein Problem mit SHFileOperations ist scheint es nicht zu unterstützen, Pfade mit mehr als 260 Zeichen, und nicht support \?\ Präfix für lange Dateinamen.
Dies ist eine echte Schmerzen....aber eine rekursive Funktion ist noch erforderlich, wenn Sie möchten, die Fähigkeit zum Umgang mit Pfaden, die länger als 260 Zeichen (Die NTFS unterstützt - aber nicht mit Windows Explorer, Eingabeaufforderung Befehle etc)
Gut, fand ich einige Fehler in diesem code.. hier ist was ich gefunden
Versuchen Sie anrufen FindClose zu schließen handle zurückgegeben durch FindFileFileA.
Sehe ich nicht ein
FindClose
für Ihredhandle
. Ein offenes handle bedeutet, dass das Verzeichnis noch in Benutzung.MSDN sagt: "Wenn das search-handle nicht mehr benötigt wird, schließen Sie es mithilfe der
FindClose
Funktion, nichtCloseHandle
."(
CloseHandle
richtig zu sein scheint für IhreDirectoryHandle
weiter unten, aber nicht für diedhandle
verwendet die Find-Schleife.)Die wichtigste Frage bereits beantwortet wurde, aber hier ist etwas, was ich bemerkt. Ihre wichtigsten
while
Schleife scheint ein wenig zerbrechlich auf mich...Diese endet, wenn
FindNextFile
endet, weil es keine mehr Dateien in dem Verzeichnis. Aber was ist, wenn es jemals enden es dafür andere Gründe? Falls etwas abnormales geschieht, es scheint, Sie könnten am Ende mit einem unendlichen loop.Ich würde denken, wenn
FindNextFile
fehl alle Grund, dann werden Sie wollen, um die Schleife zu stoppen und starten Sie die Rückgabe durch die rekursiven Aufrufe. Also ich würde vorschlagen, einfach entfernen derGetLastError
testen und es "else break;
"Eigentlich, nach einigem überlegen würde ich wahrscheinlich nur reduzieren Sie es auf: