Search code examples
c#c++windows-shell

SHChangeNotify in Windows 10 not updating Quick Access items


It seems like calling SHChangeNotify in Windows does not call an update to the items in the QuickAccess pane (or any custom-namespace folders found on the left side of Explorer). Seems like expanding the tree on the left side to the folder works alright, as well as anything in the main view on the right side.

We are calling the SHChangeNotify from a c# WPF app, though the SHChangeNotify seems to call into our DLL hook in explorer just fine for anything in the right view. This will eventually call into a named-pipe that will hook back into our c# code to call an update to the file or folder's icon.

This is what we are calling from c#:

[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern void SHChangeNotify(
    int wEventId,
    uint uFlags,
    IntPtr dwItem1,
    IntPtr dwItem2);

var ptr = Marshal.StringToHGlobalUni(fullPath);
SHChangeNotify((int)SHCNE.SHCNE_UPDATEITEM, (int)(SHCNF.SHCNF_PATHW | SHCNF.SHCNF_FLUSHNOWAIT), ptr, IntPtr.Zero);
Marshal.FreeHGlobal(ptr);

We can assume that all consts and enums are defined correctly.

This is what the icons look like: Example of mismatched icons

Note that the gray icon is the default icon. The green icon in the main window was triggered by calling the function above with the path C:\Users\Test User\Pocket Test. I would think that this should trigger a refresh for both folders.

I've also tried replacing SHCNF_FLUSHNOWAIT with SHCNF_FLUSH. I'm at a loss on how to procede here. Any any ideas on how to force-update the folders on that left pane in Explorer?


Solution

  • The Quick Access virtual folder path, as a string, is shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}, (this guid name is CLSID_HomeFolder).

    So, you can force a refresh of all items under this virtual folder with a call to:

    SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATHW, L"shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}", NULL);
    

    If you want to refresh only a specific set of children, just get the PIDL or the path of these items and call SHChangeNotify(SHCNE_UPDATEITEM, ...) on each.