C ++如何做到,这样我的程序就不会删除正在使用的文件?

问题描述 投票:0回答:2

因此,基本上,我列出了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);
        }
    }
}
c++ winapi delete-file
2个回答
1
投票

捕获异常,只需忽略该错误并继续。或使用第二种形式并传递error_code参数。比没有异常,您可以检查失败的原因。

如果文件正在使用中,则会出现错误。因此,您无法删除它。如果您没有权限,也无法删除它。

首先检查使用情况是竞争条件。检查之后,文件可能会关闭,您也许可以安全地删除它。先检查然后删除还是尝试删除它没有区别。


0
投票

这是我想出的。使用CreateFile的递归删除功能。我的原始评论

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

不是100%正确。 dwDesiredAccess应为0dwShareMode应为FILE_SHARE_DELETEdwCreationDisposition应为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包含关键部分。

© www.soinside.com 2019 - 2024. All rights reserved.