cfapi CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS反复回叫

问题描述

我正在使用cfapi,正在尝试扩展https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/CloudMirror此处的示例项目

特别是,我们正在寻求实现CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS来按需提供目录内容。我们的回调注册如下:-

CF_CALLBACK_REGISTRATION FakeCloudProvider::s_MirrorCallbackTable[] =
{
    { CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS,FakeCloudProvider::OnFetchPlaceholders },{ CF_CALLBACK_TYPE_FETCH_DATA,FakeCloudProvider::OnFetchData },{ CF_CALLBACK_TYPE_CANCEL_FETCH_DATA,FakeCloudProvider::OnCancelFetchData },CF_CALLBACK_REGISTRATION_END
};

OnFetchPlaceholders方法调用CfExecute()以使用服务器目录中关联文件的占位符数组来响应回调。

CF_OPERATION_INFO opInfo = { 0 };
CF_OPERATION_ParaMETERS opParams = { 0 };

opInfo.StructSize = sizeof(opInfo);
opInfo.Type = CF_OPERATION_TYPE_TRANSFER_PLACEHOLDERS;
opInfo.ConnectionKey = callbackInfo->ConnectionKey;
opInfo.TransferKey = callbackInfo->TransferKey;

opParams.ParamSize = sizeof(opParams);
opParams.TransferPlaceholders.CompletionStatus = status;
opParams.TransferPlaceholders.Flags = CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_NONE;
opParams.TransferPlaceholders.PlaceholderArray = placeholders;
opParams.TransferPlaceholders.PlaceholderCount = placeholdersCount;
opParams.TransferPlaceholders.PlaceholderTotalCount.QuadPart = placeholdersCount;

winrt::check_hresult(CfExecute(&opInfo,&opParams));

出乎意料的是,服务器目录中只有三个文件,没有子目录,OnFetchPlacehodlers函数快速连续调用了多次(在我刚刚进行的测试中为457次)-导致Explorer停止响应一段时间。奇怪的是,该方法调用次数似乎在200到500之间变化,但是似乎没有任何可识别的模式。

我尝试在回调中设置标志CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_disABLE_ON_DEMAND_POPULATION,当我这样做时,我们仅被调用一次,但是一旦被设置,就再也不会要求我们提供占位符,即使我们有新的占位符也是如此。

解决方法

我相信文件夹在第一次访问时只需填充一次,然后您将需要使用其他方法使其内容同步(例如,定期拉服务器)。

根据我使用API​​的经验,如果您不禁用按需填充,则 explorer.exe SearchProtocolHost.exe ( Windows索引服务)将触发新的 FetchPlaceholders 回调,我相信这是重复触发该回调的原因,这不仅影响系统性能,还将增加服务器的负载。 / p>

如果您确实需要“吊销” CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_DISABLE_ON_DEMAND_POPULATION ,只需调用here API并传递CfUpdatePlacehoder标志,即可-启用按需填充,以后对该文件夹的任何访问将再次触发FETCH_PLACEHOLDERS回调。