admin管理员组

文章数量:1565357

文章目录

  • 1、简介
    • 1.1、问题描述
    • 1.2、解决方案
  • 2、源代码
    • 2.1、WinAPI调用
    • 2.2、两行代码解决Release版本根目录驱动问题
    • 2.3、解决部分文件删除不成功的问题
  • 3、QFileInfo官方说明
  • 4、Qt 5.15版本的功能

1、简介

写这篇文章之前,已经看过很多类似的文章,都没有实质性的解决这个问题。

1.1、问题描述

原本程序在main函数中直接调用WinAPI删除文件或者文件夹到回收站,无论在Debug版本还是Release版本都不会有问题。但是如果封装成函数或者类,在栈中或者堆中去执行的时候,Release版本的驱动器根目录下就会必然不成功。

1.2、解决方案

看了Windows回收站的工作原理,才知道文件或者文件夹在删除到回收站时,实际上并没有被删除而是从所在目录更改到所在磁盘的Recycled文件夹。Recycled这个文件夹实际上是不公开的,可以通过更改计算机属性得到。就算我们清空回收站,也是将文件在注册表中的信息删除,硬盘中还有此文件,只不过通过正常方式找不到,并且其磁区不受保护,可能会被其他文件占据。

那么我们是不是就可以从这点入手,既然Debug版本没问题和Release版本有问题,但是接口依然能执行成功,我怀疑是Qt的Release版本在执行函数时,没有对文件信息进行更新获取。那么只需要更新获取一下此文件的信息就能解决此问题。

2、源代码

2.1、WinAPI调用

// 删除文件到回收站
bool deleteFileToCrash(QString name)
{
    qDebug() << "deleteStr name:" << name;
    bool ret = true;
    LPCTSTR lpSourceFile = name.toStdWString().c_str();
    SHFILEOPSTRUCT opRecycle;
    ZeroMemory(&opRecycle, sizeof(opRecycle));
    TCHAR ToBuf[MAX_PATH];
    TCHAR FromBuf[MAX_PATH];
    ZeroMemory(ToBuf, sizeof(ToBuf));
    ZeroMemory(FromBuf, sizeof(FromBuf));
    lstrcpy(FromBuf, lpSourceFile);

    opRecycle.hwnd              = Q_NULLPTR;
    opRecycle.wFunc             = FO_DELETE;
    opRecycle.pFrom             = FromBuf;
    opRecycle.pTo               = ToBuf;
    opRecycle.fFlags            = FOF_ALLOWUNDO | FOF_SILENT;
    opRecycle.fAnyOperationsAborted = FALSE;
    opRecycle.hNameMappings     = Q_NULLPTR;
    opRecycle.lpszProgressTitle = Q_NULLPTR;
    int returnVal = SHFileOperation(&opRecycle);
    qDebug() << "SHFileOperation end" << returnVal << opRecycle.fAnyOperationsAborted << GetLastError();
    if(returnVal != 0 || (opRecycle.fAnyOperationsAborted)) {
        qDebug() << "deleteFileToCrash error:" << returnVal;
        ret = false;
    }
    return ret;
}

2.2、两行代码解决Release版本根目录驱动问题

    QFileInfo fInfo(name);
    Q_UNUSED(fInfo)  // 这行代码只是不想使用这个fInfo

2.3、解决部分文件删除不成功的问题

是因为Windows对线程分配资源的问题,简单有效的方式:

        QFuture<bool> isOK = QtConcurrent::run(this, &SFileManager::deleteFileToCrash, QDir::toNativeSeparators(path));

3、QFileInfo官方说明

4、Qt 5.15版本的功能

QFile::moveToTrash方法将文件移动到垃圾箱或者回收站,在此版本之前的版本只能通过我写的方式去删除哈。

本文标签: 之路回收站详解文件夹文件