Programatically ask Windows Explorer to refresh Portable device folder contents
See the question and my original answer on StackOverflowHere is some sample code that scans all opened Windows Explorer views and refresh all views that currently display a portable device Shell Item (using WPD properties), you can adapt it to filter the exact view(s) you want to target:
#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"display 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"WPD name:%s\n", name.m_pData);
PropVariantClear(&pv);
if (isWpd)
{
// ask for refresh
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, pidl, NULL);
}
}
}
CoUninitialize();
}