从 c# 更新图像缩略图
Posted
技术标签:
【中文标题】从 c# 更新图像缩略图【英文标题】:Update Image Thumbnail from c# 【发布时间】:2020-07-26 18:36:04 【问题描述】:我在 Win 10 的 WinForms 应用程序中以 C# 编程方式处理 JPEG 图像,并希望文件资源管理器显示处理后的图像而不是原始图像缩略图。关闭资源管理器,删除 %LocalAppData%\Microsoft\Windows\Explorer\thumbcache_*.db 并重新启动会这样做,但它很慢而且很麻烦。我想以编程方式更新单个文件的缩略图。当通过资源管理器上下文菜单旋转图像时,Windows 会执行此操作,但从程序中执行此操作的方法尚不清楚。
我目前用来关闭资源管理器,删除缩略图缓存文件并重新启动的批处理文件是
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"
【问题讨论】:
没有什么有用的,我可以以编程方式运行。 Explorer Rotate 选项会更改缩略图。 2010年***.com/questions/3555799/…中描述的尝试方法,但在Win 10中不起作用。 【参考方案1】:执行此类操作的正确方法是使用SHChangeNotify()
函数。如果您使用的是 C#,您可以像这样 p/invoke 它:
[DllImport( "Shell32.dll", CharSet = CharSet.Auto, SetLastError = true )]
static extern void SHChangeNotify(uint wEventId, uint uFlags, [MarshalAs(UnmanagedType.LPWStr)] string dwItem1, IntPtr dwItem2);
...然后用它来通知资源管理器某个项目已被修改(即您操作的图像):
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);
【讨论】:
您可以像这样使用 item1(和/或 item2)声明 SHChangeNotify 以避免分配:[MarshalAs(UnmanagedType.LPWStr)] string dwItem1
尝试了这个建议,改变了 SHChangeNotify 的第三个参数是一个整数指针而不是一个字符串,如下intPtr pidl; SHParseDisplayName(path, IntPtr.Zero, out pidl, 0, out iAttribute); SHChangeNotify( SHCNE_UPDATEITEM, SHCNF_FLUSH|SHCNF_PATHW, pidl, IntPtr.Zero);
,但在 Win 10 上的资源管理器中仍然没有改变缩略图。
由于 SHChangeNotify 的不同声明如下internal static extern void SHChangeNotify( UInt32 wEventId, UInt32 uFlags, IntPtr dwItem1, IntPtr dwItem2
而需要整数指针。更改为 Dmitry Brant 提供的路径并将路径作为字符串传递也没有更改缩略图。
研究表明从外壳外部调用 SHChangeNotify 可能不起作用。这可以解释观察结果。【参考方案2】:
将文件修改日期增加 1 秒,然后将其改回会触发 Windows 认为文件已更改,因此缩略图已更新。使用的代码是
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));
【讨论】:
以上是关于从 c# 更新图像缩略图的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 C# 代码在 Android 上的 Unity3D 中创建图像缩略图?