以编程方式要求资源管理器刷新便携式设备文件夹内容

问题描述 投票:0回答:1

我想以编程方式要求资源管理器刷新 MTP 文件夹内容(Android 设备)并显示现有文件(模拟文件夹上的 F5)。如果它是带有驱动器号的标准路径,我可以使用以下方式刷新:

SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, FolderPath, NULL);

但是,MTP 文件夹没有我可以使用的驱动器号路径。我如何要求资源管理器刷新此类文件夹,或者要求资源管理器刷新所有打开的文件夹窗口?

c++ winapi explorer mtp
1个回答
0
投票

这里是一些示例代码,用于扫描所有打开的 Windows 资源管理器视图并刷新当前显示便携式设备 Shell 项目的所有视图(使用 WPD 属性),您可以对其进行调整以过滤您想要定位的确切视图:

#include <windows.h>
#include <stdio.h>
#include <atlbase.h>
#include <shobjidl_core.h>
#include <shlobj_core.h>
#include <ShlGuid.h>
#include <PortableDevice.h>
#include <propvarutil.h>

int main()
{
  CoInitialize(nullptr);
  {
    // get Shell windows' list
    CComPtr<IShellWindows> windows;
    ATLASSERT(SUCCEEDED(windows.CoCreateInstance(CLSID_ShellWindows)));

    // browse all opened views, pick the path or display name that you need
    long count = 0;
    windows->get_Count(&count);
    for (auto i = 0; i < count; i++)
    {
      CComPtr<IDispatch> disp;
      ATLASSERT(SUCCEEDED(windows->Item(CComVariant(i), &disp)));

      // get the PIDL from the underlying IShellView
      CComPtr<IPersistIDList> idlist;
      ATLASSERT(SUCCEEDED(IUnknown_QueryService(disp, SID_SFolderView, IID_PPV_ARGS(&idlist))));

      CComHeapPtr<ITEMIDLIST> pidl;
      ATLASSERT(SUCCEEDED(idlist->GetIDList(&pidl)));

      // get this as an IShellItem, easier to work with
      CComPtr<IShellItem2> item;
      ATLASSERT(SUCCEEDED(SHCreateItemFromIDList(pidl, IID_PPV_ARGS(&item))));

      CComHeapPtr<wchar_t> displayName;
      ATLASSERT(SUCCEEDED(item->GetDisplayName(SIGDN::SIGDN_DESKTOPABSOLUTEEDITING, &displayName)));
      wprintf(L"name:%s\n", displayName.m_pData);

      CComHeapPtr<wchar_t> path;
      ATLASSERT(SUCCEEDED(item->GetDisplayName(SIGDN::SIGDN_DESKTOPABSOLUTEPARSING, &path)));
      wprintf(L"path:%s\n", path.m_pData);

      // if you want to make sure it's a WPD object, you can get a WPD property
      // for example WPD_OBJECT_NAME (should be the same as SIGDN_NORMALDISPLAY)
      PROPVARIANT pv;
      PropVariantInit(&pv);
      ATLASSERT(SUCCEEDED(item->GetProperty(WPD_OBJECT_NAME, &pv))); // PortableDevice.h

      // here we refresh all WPD views
      auto isWpd = pv.vt != VT_EMPTY;

      CComHeapPtr<wchar_t> name;
      ATLASSERT(SUCCEEDED(PropVariantToStringAlloc(pv, &name))); // propvarutil.h
      wprintf(L"name:%s\n", name.m_pData);
      PropVariantClear(&pv);
      if (isWpd)
      {
        // ask for refresh
        SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, pidl, NULL);
      }
    }
  }
  CoUninitialize();
}
© www.soinside.com 2019 - 2024. All rights reserved.