首页 > 解决方案 > 为 CFAPI 设置状态图标无法按预期工作

问题描述

我尝试将使用 CFAPI 创建的占位符文件的状态图标设置为错误。(见下文)

带有错误图标的屏幕

文件夹 T 的内容:
带有云符号的屏幕

我在文件上设置了错误状态,但它不显示错误。但是,错误显示在包含的文件夹中。

我使用以下代码在文件上设置错误(完整代码发布在github 上):

void SetTransferStatus(_In_ PCWSTR fullPath, _In_ SYNC_TRANSFER_STATUS status)
{
    // Tell the Shell so File Explorer can display the progress bar in its view
    try
    {
        // First, get the Volatile property store for the file. That's where the properties are maintained.
        winrt::com_ptr<IShellItem2> shellItem;
        winrt::check_hresult(SHCreateItemFromParsingName(fullPath, nullptr, __uuidof(shellItem), shellItem.put_void()));

        winrt::com_ptr<IPropertyStore> propStoreVolatile;
        winrt::check_hresult(
            shellItem->GetPropertyStore(
                GETPROPERTYSTOREFLAGS::GPS_READWRITE | GETPROPERTYSTOREFLAGS::GPS_VOLATILEPROPERTIESONLY,
                __uuidof(propStoreVolatile),
                propStoreVolatile.put_void()));

        // Set the sync transfer status accordingly
        PROPVARIANT transferStatus;
        winrt::check_hresult(
            InitPropVariantFromUInt32(
                status,
                &transferStatus));
        winrt::check_hresult(propStoreVolatile->SetValue(PKEY_SyncTransferStatus, transferStatus));

        // Without this, all your hard work is wasted.
        winrt::check_hresult(propStoreVolatile->Commit());

        // Broadcast a notification that something about the file has changed, so that apps
        // who subscribe (such as File Explorer) can update their UI to reflect the new progress
        SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, static_cast<LPCVOID>(fullPath), nullptr);

        //wprintf(L"Succesfully Set Transfer Progress on \"%s\" to %llu/%llu\n", fullPath, completed, total);
    }
    catch (...)
    {
        // winrt::to_hresult() will eat the exception if it is a result of winrt::check_hresult,
        // otherwise the exception will get rethrown and this method will crash out as it should
        wprintf(L"Failed to Set Transfer Progress on \"%s\" with %08x\n", fullPath, static_cast<HRESULT>(winrt::to_hresult()));
    }
}

另外,如果我删除文件并创建一个新文件,状态仍然会出错。

标签: c++windowswinapiminifilter

解决方案


有人向我指出了 windows cloud mirror 示例中的拉取请求,该示例显示了如何完成此操作。

这是代码:

void Utilities::UpdateErrorOnItem(PCWSTR path, bool setError)
{
    try
    {
        winrt::com_ptr<IShellItem2> item;
        winrt::check_hresult(SHCreateItemFromParsingName(path, nullptr, IID_PPV_ARGS(item.put())));

        winrt::com_ptr<IPropertyStore> propertyStore;
        winrt::check_hresult(item->GetPropertyStore(GPS_READWRITE | GPS_EXTRINSICPROPERTIESONLY, IID_PPV_ARGS(propertyStore.put())));

        PROPVARIANT propVar{};
        if (setError)
        {
            propVar.vt = VT_UI4;
            propVar.ulVal = static_cast<unsigned long>(E_FAIL);
            winrt::check_hresult(propertyStore->SetValue(PKEY_LastSyncError, propVar));
        }
        else
        {
            // Clear by setting to empty
            propVar.vt = VT_EMPTY;
            winrt::check_hresult(propertyStore->SetValue(PKEY_LastSyncError, propVar));
        }

        winrt::check_hresult(propertyStore->Commit());
    }
    catch (...)
    {
        // winrt::to_hresult() will eat the exception if it is a result of winrt::check_hresult,
        // otherwise the exception will get rethrown and this method will crash out as it should
        wprintf(L"Failed to set error state with %08x\n", static_cast<HRESULT>(winrt::to_hresult()));
    }


推荐阅读