-1

I am manipulating JPEG images programmatically from C# in a WinForms app in Win 10 and would like File Explorer to show the manipulated rather than the original image thumbnail. Closing Explorer, deleting %LocalAppData%\Microsoft\Windows\Explorer\thumbcache_*.db and restarting does this but it is slow and intrusive. I would like to update an individual file's thumbnail programmatically. Windows does this when an image is rotated via the Explorer context menu, but the means for doing this from a program aren't clear.

The batch file which I currently use to close Explorer, delete the thumbnail cache file and restart is

taskkill /f /im explorer.exe
timeout 2 /nobreak>nul
DEL /F /S /Q /A %LocalAppData%\Microsoft\Windows\Explorer\thumbcache_*.db
timeout 2 /nobreak>nul
start "" %windir%\explorer.exe
start "" %windir%\explorer.exe "Folder To Update"
Ðаn
  • 10,934
  • 11
  • 59
  • 95
SimonKravis
  • 553
  • 1
  • 3
  • 24
  • Nothing useful that I can run programmatically. Explorer Rotate option changes thumbnail though. – SimonKravis Apr 14 '20 at 04:54
  • Tried method described in https://stackoverflow.com/questions/3555799/how-do-i-refresh-a-files-thumbnail-in-windows-explorer in 2010, but does not work in Win 10. – SimonKravis Apr 14 '20 at 08:26

2 Answers2

0

The proper way to do something like this is to use the SHChangeNotify() function. If you're using C#, you can p/invoke it like so:

[DllImport( "Shell32.dll", CharSet = CharSet.Auto, SetLastError = true )]
static extern void SHChangeNotify(uint wEventId, uint uFlags, [MarshalAs(UnmanagedType.LPWStr)] string dwItem1, IntPtr dwItem2);

...and then use it to notify Explorer that an item has been modified (i.e. the image that you manipulated):

private const uint SHCNE_UPDATEITEM = 0x00002000;
private const uint SHCNF_PATHW = 0x0005;
private const uint SHCNF_FLUSH = 0x1000;

string pathName = "your image file.jpg"

SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATHW | SHCNF_FLUSH, pathName, IntPtr.Zero);
Dmitry Brant
  • 7,612
  • 2
  • 29
  • 47
  • 1
    You can declare SHChangeNotify with item1 (and/or item2) like this to avoid allocations: `[MarshalAs(UnmanagedType.LPWStr)] string dwItem1` – Simon Mourier Apr 15 '20 at 13:54
  • Tried this suggestion with the change that 3rd argument of SHChangeNotify is an integer pointer rather than a string as follows `intPtr pidl; SHParseDisplayName(path, IntPtr.Zero, out pidl, 0, out iAttribute); SHChangeNotify( SHCNE_UPDATEITEM, SHCNF_FLUSH|SHCNF_PATHW, pidl, IntPtr.Zero);` but still does not change thumbnail in Explorer on Win 10. – SimonKravis Apr 16 '20 at 02:02
  • The integer pointer was needed due to a different declaration of SHChangeNotify as follows `internal static extern void SHChangeNotify( UInt32 wEventId, UInt32 uFlags, IntPtr dwItem1, IntPtr dwItem2`. Changing to one supplied by Dmitry Brant and passing path as string did not change thumbnail either. – SimonKravis Apr 16 '20 at 03:59
  • Research indicates that calls to SHChangeNotify from outside the shell may not work. This may explain observations. – SimonKravis Apr 17 '20 at 02:00
-2

Increasing the file modified date by 1 sec and then changing it back triggers Windows into thinking the file has changed so that the thumbnail is updated. Code used is

DateTime modDate = System.IO.File.GetLastWriteTime(sFile);
System.IO.File.SetLastWriteTime(sFile, modDate.AddSeconds(1.0));
System.IO.File.SetLastWriteTime(sFile, modDate.AddSeconds(-1.0));
SimonKravis
  • 553
  • 1
  • 3
  • 24