一、使用Windows API函数MoveFileEx
函数原型
BOOL MoveFileEx(
LPCTSTR lpExistingFileName, // file name
LPCTSTR lpNewFileName, // new file name
DWORD dwFlags // move options
);
这里附上MSDN的官方解释
If dwFlags specifies MOVEFILE_DELAY_UNTIL_REBOOT and lpNewFileName is NULL, MoveFileEx registers the lpExistingFileName file to be deleted when the system restarts. If lpExistingFileName refers to a directory, the system removes the directory at restart only if the directory is empty.
注意到这里写的,MoveFileEx
可以删除目录,只能当目录为空的时候,那这里只能循环遍历文件夹遍历清空了
二、寻找遍历文件夹的方法
参考博客c++利用windows api遍历指定文件夹及其子文件夹中的文件
#include "stdafx.h"
#include <iostream>
#include "windows.h"
#include <string.h>
#include <Strsafe.h>
using namespace std;
//传入要遍历的文件夹路径,并遍历相应文件夹
void TraverseDirectory(wchar_t Dir[MAX_PATH])
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind=INVALID_HANDLE_VALUE;
wchar_t DirSpec[MAX_PATH]; //定义要遍历的文件夹的目录
DWORD dwError;
StringCchCopy(DirSpec,MAX_PATH,Dir);
StringCchCat(DirSpec,MAX_PATH,TEXT("\\*")); //定义要遍历的文件夹的完整路径\*
hFind=FindFirstFile(DirSpec,&FindFileData); //找到文件夹中的第一个文件
if(hFind==INVALID_HANDLE_VALUE) //如果hFind句柄创建失败,输出错误信息
{
FindClose(hFind);
return;
}
else
{
while(FindNextFile(hFind,&FindFileData)!=0) //当文件或者文件夹存在时
{
if((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0&&wcscmp(FindFileData.cFileName,L".")==0||wcscmp(FindFileData.cFileName,L"..")==0) //判断是文件夹&&表示为"."||表示为"."
{
continue;
}
if((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0) //判断如果是文件夹
{
wchar_t DirAdd[MAX_PATH];
StringCchCopy(DirAdd,MAX_PATH,Dir);
StringCchCat(DirAdd,MAX_PATH,TEXT("\\"));
StringCchCat(DirAdd,MAX_PATH,FindFileData.cFileName); //拼接得到此文件夹的完整路径
TraverseDirectory(DirAdd); //实现递归调用
}
if((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)==0) //如果不是文件夹
{
wcout<<Dir<<"\\"<<FindFileData.cFileName<<endl; //输出完整路径
}
}
FindClose(hFind);
}
}
int _tmain( int argc, wchar_t *argv[ ], wchar_t *envp[ ] )
{
locale loc( "chs" ); //支持中文输出,否则wchar可能无法输出值为中文的变量
wcout.imbue( loc );
TraverseDirectory(L"C:\\Users\\v_tianboli\\Desktop\\windows程式设计开发指南"); //遍历指定的文件夹,此处文件路径可按具体情况修改
system("pause");
return 0;
}
三、编写DeleteAllFileReboot样例程序
这里暂时使用了SOUI的界面库作为载体。核心函数中暂时使用DeleteFile
进行测试:
HRESULT CMainDlg::DeleteFolder(wchar_t Dir[MAX_PATH])
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
wchar_t DirSpec[MAX_PATH]; //定义要遍历的文件夹的目录
DWORD dwError;
StringCchCopy(DirSpec, MAX_PATH, Dir);
StringCchCat(DirSpec, MAX_PATH, TEXT("\\*")); //定义要遍历的文件夹的完整路径\*
hFind = FindFirstFile(DirSpec, &FindFileData); //找到文件夹中的第一个文件
if (hFind == INVALID_HANDLE_VALUE) //如果hFind句柄创建失败,输出错误信息
{
FindClose(hFind);
return S_FALSE;
} else {
while (FindNextFile(hFind, &FindFileData) != 0)//当文件或者文件夹存在时
{
if ((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0 && wcscmp(FindFileData.cFileName, L".") == 0 || wcscmp(FindFileData.cFileName, L"..") == 0) //判断是文件夹&&表示为"."||表示为"."
{
continue;
}
if ((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0) //判断如果是文件夹
{
wchar_t DirAdd[MAX_PATH];
StringCchCopy(DirAdd, MAX_PATH, Dir);
StringCchCat(DirAdd, MAX_PATH, TEXT("\\"));
StringCchCat(DirAdd, MAX_PATH, FindFileData.cFileName); //拼接得到此文件夹的完整路径
DeleteFolder(DirAdd); //实现递归调用
}
if ((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) == 0) //如果不是文件夹
{
//拼出完整路径
if (0 != wcscmp(FindFileData.cFileName, L"test_delete_file.txt")) {
SStringW strFileName;
strFileName.Format(L"%s\\%s", Dir, FindFileData.cFileName);
// DeleteFile(strFileName);
MoveFileEx(strFileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
}
}
}
FindClose(hFind);
}
return S_OK;
}
调用处需要能够弹出选择文件夹的选择窗口,这里参考了[Win32]打开文件/保存文件/选择文件夹对话框博客里面的方法:
HRESULT CMainDlg::OnChooseFolder()
{
TCHAR szBuffer[MAX_PATH] = {0};
BROWSEINFO bi = {0};
bi.hwndOwner = NULL; //拥有着窗口句柄,为NULL表示对话框是非模态的,实际应用中一般都要有这个句柄
bi.pszDisplayName = szBuffer; // 接收文件夹的缓冲区
bi.lpszTitle = TEXT("选择一个文件夹"); // 标题
bi.ulFlags = BIF_NEWDIALOGSTYLE;
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if (SHGetPathFromIDList(idl, szBuffer)) {
SOUI::SWindow *pText = FindChildByName2<SOUI::SWindow>(L"text_folder_path");
assert(pText);
pText->SetWindowText(szBuffer);
} else {
SMessageBox(NULL, TEXT("请选择一个文件夹"), NULL, MB_ICONERROR);
}
return S_OK;
}
稍微完善下代码,现在已经完成了指定目录,可以删除指定目录下除了文件夹之外的所有内容的功能。