问题描述
我正在使用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回调。