如何使用IFileOperation删除文件并将其发送到Vista / 7中的回收站?

时间:2017-06-25 00:04:58

标签: winapi

根据IFileOperation::SetOperationFlags的文档,Windows 8中引入了FOFX_RECYCLEONDELETE标记。

我想删除文件并将其发送到回收站。如何在Vista和Windows 7中使用IFileOperation进行此操作?

我知道SHFileOperation支持该功能,但我不想使用SHFileOperation,因为Microsoft告诉我们在其位置使用IFileOperation。这可能是使用IFileOperation,如果可以的话,该如何完成?

3 个答案:

答案 0 :(得分:2)

SetOperationFlags的文档说:

  

此成员可以是以下标志的组合。 FOF标志在She​​llapi.h中定义,FOFX标志在Shobjidl.h中定义。

因此,您可以使用与FOF_ALLOWUNDO一起使用的完全相同的标记SHFileOperation来指示删除操作以移动到回收站。

答案 1 :(得分:0)

  

在Win 8中引入了FOFX_RECYCLEONDELETE标志 - 它是否可以在Vista / 7中运行?

由于{8}在Windows 8中引入,因此它在Vista / 7中不存在,所以不,它在这些版本中不起作用。

  

总是有SHFileOperation,但我宁愿使用更新的Win32 API方法。还有什么需要知道的吗?回收文件/文件夹的其他方法是什么?

FOFX_RECYCLEONDELETE是唯一记录回收文件/文件夹的方法:

  

当用于删除文件时,除非在lpFileOp指向的SHFILEOPSTRUCT结构的fFlags成员中设置FOF_ALLOWUNDO标志,否则SHFileOperation将永久删除该文件。 设置该标志将文件发送到回收站。如果您只想删除文件并保证文件没有放在回收站中,请使用DeleteFile。

同一个标志在SHFileOperation()中可用,但其记录的行为不同:

  

如果可能,请保留撤消信息。

     

在Windows Vista之前,只能从执行原始操作的同一进程撤消操作

     

在Windows Vista和更高版本的系统中,撤消的范围是用户会话。在用户会话中运行的任何进程都可以撤消另一个操作。 撤消状态保存在Explorer.exe进程中,只要该进程正在运行,它就可以协调撤消功能。

这就是为什么必须引入IFileOperation - 重新添加在FOFX_RECYCLEONDELETE首次引入时丢失的旧回收站行为。

答案 2 :(得分:0)

我已经验证了David Heffernan对FOF_ALLOWUNDO标志与IFileOperation一起使用以将项目发送到回收站的评估。这是代码。显然,SHCreateItemFromParsingName是MS说从字符串创建项目的方式。此代码适用于Qt的C ++。首先,你必须首先初始化COM。

void Worker::deleteItem(QString item)
{
    HRESULT hr;
    IFileOperation *pfo;

    wchar_t *itemWChar = new wchar_t[item.length()+1];
    item.toWCharArray(itemWChar);
    itemWChar[item.length()] = 0;
    PCWSTR itemPCWSTR = itemWChar;

    hr = CoCreateInstance(CLSID_FileOperation,
                          NULL,
                          CLSCTX_ALL,
                          //IID_IFileOperation,
                          IID_PPV_ARGS(&pfo));
    if (!SUCCEEDED(hr))
    {
        //error handling here
        return;
    }

    hr = pfo->SetOperationFlags(FOF_ALLOWUNDO | FOF_NOCONFIRMATION);
    if (!SUCCEEDED(hr))
    {
        //error handling here
        return;
    }

    IShellItem *deleteItem = NULL;
    hr = SHCreateItemFromParsingName(itemPCWSTR,
                                     NULL,
                                     IID_PPV_ARGS(&deleteItem));
    if (!SUCCEEDED(hr))
    {
        //error handling here
        return;
    }

    hr = pfo->DeleteItem(deleteItem,NULL);

    if (deleteItem != NULL)
    {
        deleteItem->Release();
    }


    if (!SUCCEEDED(hr))
    {
        //error handling here
        return;
    }

    hr = pfo->PerformOperations();

    if (!SUCCEEDED(hr))
    {
        //error handling here
        return;
    }

    pfo->Release();

    delete[] itemWChar;
}