简体   繁体   English

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

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

So basically, I'm listing all of the files in my temp directory, and then deleting them.所以基本上,我列出了临时目录中的所有文件,然后删除它们。 Obviously, some of the files are in use and the program itself is using the files that it's deleting.显然,一些文件正在使用中,而程序本身正在使用它正在删除的文件。 I tried fiddling around with SHFileOperation with no success.我尝试摆弄SHFileOperation但没有成功。 (tbh I got no idea how to use it). (说实话我不知道如何使用它)。 How do I make it check if the file is in use by another program before deleting it?如何让它在删除文件之前检查该文件是否正在被另一个程序使用? Thanks!谢谢!

This is giving me the error: fs::remove_all(entry.path());这给了我错误: fs::remove_all(entry.path());

Code:代码:

#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);
        }
    }
}

Catch the exception Just ignore the error and continue.捕获异常忽略错误并继续。 Or use the second form and pass an error_code argument.或者使用第二种形式并传递一个error_code参数。 Than you get no exception and you can check the reason why it failed.比你没有例外,你可以检查它失败的原因。

If the file is in use you get an error.如果文件正在使用中,则会出现错误。 So you can't delete it.所以你不能删除它。 If you have no rights you can't delete it too.如果你没有权限,你也不能删除它。

Checking the usage first is a race condition.首先检查使用情况是竞争条件。 After the check, the file might get closed and you may be able to delete it safely.检查后,文件可能会关闭,您可以安全地删除它。 There is no difference in checking first and than delete it or trying to delete it and it fails.首先检查和删除它或尝试删除它但失败没有区别。

Here's what I came up with.这是我想出的。 A recursive delete function which uses CreateFile .使用CreateFile的递归删除函数。 My original comment我的原创评论

Maybe you could use CreateFile with desired access 0 and share mode OPEN_EXISTING.也许您可以使用具有所需访问权限 0 和共享模式 OPEN_EXISTING 的 CreateFile。 Then you have to check the failing reason.然后你必须检查失败的原因。 If it doesn't fail;如果没有失败; close and delete.关闭并删除。

wasn't 100% correct.不是 100% 正确。 dwDesiredAccess should be 0 , dwShareMode should be FILE_SHARE_DELETE , dwCreationDisposition should be OPEN_EXISTING and dwFlagsAndAttributes should be FILE_FLAG_DELETE_ON_CLOSE . dwDesiredAccess应该是0dwShareMode应该是FILE_SHARE_DELETEdwCreationDisposition应该是OPEN_EXISTING并且dwFlagsAndAttributes应该是FILE_FLAG_DELETE_ON_CLOSE If then a valid handle is received the last CloseHandle on the file will lead to deletion (see here ).如果收到有效句柄,文件上的最后一个CloseHandle将导致删除(参见此处)。

Here's an example:这是一个例子:

#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 contains the crucial part. tryDeleteFile包含关键部分。

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

相关问题 如何在 C++ 程序中使用下标数字? - How do I use subscript digits in my C++ program? 如何使我的程序在向 txt 文件中添加新条目时不会循环 - How do I make it so my program doesn't loop when adding new entries to a txt file 如何布局我的 C++ 程序? (我应该把 .h 和 .cpp 文件放在哪里?) - How do I layout my C++ program? (where should I put the .h and .cpp files?) 如何将c ++程序拆分为包含普通代码行(不一定是函数)的文件? - How do I split my c++ program into files that contain plain code lines, not necessarily functions? 如何使我的控制台C ++程序在后台运行? - How do I make my console C++ program work in the background? C ++如何使程序全局检测我的击键? - C++ How do I make a program detect my keystrokes globally? 如何使程序监视C ++中的文件修改? - How do I make my program watch for file modification in C++? 我怎样才能让我的 C++ 程序计数? - How can I make my c++ program to countinue? 如何在Linux上的C ++程序中使用共享库(在本例中为JsonCpp)? - How do I use a shared library (in this case JsonCpp) in my C++ program on Linux? 如何在我的 c++ 程序中初始化和使用全局结构? - How do I initialize and use a global struct in my c++ program?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM