シリーズもの一覧
1/4 https://qiita.com/macchan/items/30d81c4cb66a52fe4b0b
2/4 https://qiita.com/macchan/items/282db3e735ed0ad4bed8
3/4 https://qiita.com/macchan/items/19a06f30e8f3c553d4cb
4/4 https://qiita.com/macchan/items/9853a6d7b4e01ad4dc8d
プログラムで「ディレクトリを丸ごと削除したい」と思って調べると、意外と面倒であるじことが判ります。Windows のAPIには RemoveDirectory が用意されていますが、「パスは空のディレクトリを指定する必要がある」と注意書きがあります。
https://learn.microsoft.com/ja-jp/windows/win32/api/fileapi/nf-fileapi-removedirectorya
https://learn.microsoft.com/ja-jp/windows/win32/api/fileapi/nf-fileapi-removedirectoryw
多少のバリエーションがありますが、以下はファイル検索を再帰的に行い、ファイル削除を行ってからディレクトリを削除するプログラムです。
#include <iostream>
#include <Windows.h>
#include <string.h>
BOOL IsDir(const WIN32_FIND_DATA& rFinder);
BOOL IsDot(const WIN32_FIND_DATA& rFinder);
BOOL DelDir(const std::wstring& strDirName);
int wmain()
{
setlocale(LC_ALL, "Japanese");
BOOL bRet = DelDir(L"D:\\Work\\Dir");
std::cout << bRet << std::endl;
return 0;
}
BOOL DelDir(const std::wstring& strDirName)
{
BOOL bRet = FALSE;
// 検索用にワイルドカードを作る
const std::wstring strWork = strDirName + L"\\*";
WIN32_FIND_DATA finder;
HANDLE hFinder = FindFirstFile(strWork.data(), &finder);
if (hFinder == INVALID_HANDLE_VALUE) {
std::wcout << L"対象がみつからない " << strWork.data() << std::endl;
return FALSE;
}
if (hFinder != INVALID_HANDLE_VALUE)
{
do {
if (IsDir(finder) && IsDot(finder)) {
// "." と ".." は対象外
continue;
}
if (IsDir(finder)) {
// ディレクトリならば
// 削除するディレクトリ名を作る
const std::wstring strNextDir = strDirName + L'\\' + finder.cFileName;
// 再帰
bRet = DelDir(strNextDir);
if (!bRet) {
return bRet;
}
}
else {
// ディレクトリでないならファイル
// 削除するファイル名を作る
const std::wstring strDelFile = strDirName + L'\\' + finder.cFileName;
// ファイルを削除する
bRet = DeleteFile(strDelFile.data());
if (!bRet) {
std::wcout << L"ファイルが消せない " << strDelFile.data() << std::endl;
return bRet;
}
}
} while (FindNextFile(hFinder, &finder));
// これで該当ディレクトリ内のファイルはすべて消えたはずなので
// 最後にディレクトリを消す
bRet = RemoveDirectory(strDirName.data());
if (!bRet) {
std::wcout << L"ディレクトリが消せない " << strDirName.data() << std::endl;
return bRet;
}
FindClose(hFinder);
}
return bRet;
}
BOOL IsDir(const WIN32_FIND_DATA& rFinder)
{
return (rFinder.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}
BOOL IsDot(const WIN32_FIND_DATA& rFinder)
{
const std::wstring strFileName = rFinder.cFileName;
return ( (strFileName == L"." ) ||
(strFileName == L"..") );
}