从 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 中创建图像缩略图?

下载图像缩略图并在 ListView C# 中显示它们

使用 C# System.Drawing 生成缩略图时居中裁剪图像

图像编辑后如何更新android画廊的缩略图预览

图像编辑后如何更新android画廊的缩略图预览

如何从我的文件夹中获取缩略图?