因此,基本上,我将列出temp目录中的所有文件,然后将其删除。显然,某些文件正在使用中,程序本身正在使用要删除的文件。我尝试摆弄SHFileOperation
并没有成功。 (我不知道如何使用它)。在删除文件之前,如何检查文件是否已被其他程序使用?谢谢!
这给了我错误:fs::remove_all(entry.path());
代码:
#include <iostream>
#include <Windows.h>
#include <filesystem>
#include <lmcons.h>
#include <fileapi.h>
#include "cColors.h"
using namespace std;
namespace fs = filesystem;
char type;
int main()
{
SetConsoleTextAttribute(h, 15);
while (true)
{
cout << "[~] Are you sure you want to run Windows Cleaner? [Y/N]";
cin >> type;
if (type == 'n')
{
break;
exit(0);
}
else if (type == 'y')
{
cout << "[#] Cleaning temp directory\n";
for (const auto& entry : fs::directory_iterator(fs::temp_directory_path()))
{
cout << "[#] Deleting " << entry.path();
fs::remove_all(entry.path()); //This is giving me the error
}
}
else
{
break;
exit(0);
}
}
}
答案 0 :(得分:1)
捕获异常只需忽略该错误并继续。或使用第二种形式并传递一个error_code
参数。比没有例外,您可以检查失败的原因。
如果文件正在使用中,则会出现错误。因此,您无法删除它。如果您没有权限,也无法删除它。
首先检查使用情况是一种竞争状况。检查之后,文件可能会关闭,您也许可以安全地删除它。先检查然后删除或尝试删除它并失败都没有区别。
答案 1 :(得分:0)
这就是我想出的。使用CreateFile
的递归删除功能。我的原始评论
也许您可以将CreateFile与所需的访问权限0一起使用,并将共享模式设为OPEN_EXISTING。然后,您必须检查失败的原因。如果没有失败;关闭并删除。
不是100%正确。 dwDesiredAccess 应该为0
, dwShareMode 应该为FILE_SHARE_DELETE
, dwCreationDisposition 应该为OPEN_EXISTING
和 dwFlagsAndAttributes 应该为FILE_FLAG_DELETE_ON_CLOSE
。如果然后收到有效的句柄,则文件上的最后一个CloseHandle
将导致删除(请参见here)。
这是一个例子:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <tchar.h>
#include <iostream>
#include <filesystem>
#ifdef _UNICODE
auto& cout = std::wcout;
#else
using std::cout;
#endif // _UNICODE
using std::endl;
namespace fs=std::filesystem;
void deleteRecursive(const fs::path& path);
void tryDeleteFile(const fs::path& path);
int main(int argc, char* argv[])
{
TCHAR tempDir[255];
GetEnvironmentVariable(_T("TEMP"), tempDir, 255);
deleteRecursive(fs::path(tempDir));
return 0;
}
void deleteRecursive(const fs::path& path)
{
fs::directory_iterator dirs(path);
for (const auto& entry : dirs)
{
const auto& path = entry.path();
if (entry.is_directory())
{
deleteRecursive(path);
if (fs::is_empty(path))
{
if (!RemoveDirectory(path.c_str()))
{
cout << _T("Can't delete dir: ") << path << endl;
}
}
}
else
{
tryDeleteFile(path);
}
}
}
void tryDeleteFile(const fs::path& path)
{
const auto file = path.c_str();
HANDLE fileHandle = CreateFile(
file, // lpFileName,
0, // dwDesiredAccess,
FILE_SHARE_DELETE, // dwShareMode,
NULL, // lpSecurityAttributes,
OPEN_EXISTING, // dwCreationDisposition,
FILE_FLAG_DELETE_ON_CLOSE, // dwFlagsAndAttributes,
NULL // hTemplateFile
);
if (fileHandle == INVALID_HANDLE_VALUE)
{
DWORD lastErr = GetLastError();
if (lastErr != ERROR_FILE_NOT_FOUND) // gone in the mean time
{
cout << _T("Can't delete file: ") << file << endl;
}
}
else
{
CloseHandle(fileHandle);
}
}
tryDeleteFile
包含关键部分。