繁体   English   中英

C++ 如何使我的程序不会删除正在使用的文件?

[英]C++ How do I make it so my program wouldn't delete files that are in use?

所以基本上,我列出了临时目录中的所有文件,然后删除它们。 显然,一些文件正在使用中,而程序本身正在使用它正在删除的文件。 我尝试摆弄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);
        }
    }
}

捕获异常忽略错误并继续。 或者使用第二种形式并传递一个error_code参数。 比你没有例外,你可以检查它失败的原因。

如果文件正在使用中,则会出现错误。 所以你不能删除它。 如果你没有权限,你也不能删除它。

首先检查使用情况是竞争条件。 检查后,文件可能会关闭,您可以安全地删除它。 首先检查和删除它或尝试删除它但失败没有区别。

这是我想出的。 使用CreateFile的递归删除函数。 我的原创评论

也许您可以使用具有所需访问权限 0 和共享模式 OPEN_EXISTING 的 CreateFile。 然后你必须检查失败的原因。 如果没有失败; 关闭并删除。

不是 100% 正确。 dwDesiredAccess应该是0dwShareMode应该是FILE_SHARE_DELETEdwCreationDisposition应该是OPEN_EXISTING并且dwFlagsAndAttributes应该是FILE_FLAG_DELETE_ON_CLOSE 如果收到有效句柄,文件上的最后一个CloseHandle将导致删除(参见此处)。

这是一个例子:

#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包含关键部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM