CFAPI 的设置状态图标无法按预期工作

Setting Status icon for CFAPI does not work as expected

我尝试将使用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()));
    }
}

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

有人向我指出了 windows 云镜像示例中的 pull request,它展示了如何完成此操作。

这是代码:

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