c# – 访问不存在的缩略图
我已经提出了一个应用程序,向您显示计算机中的文件列表.每当您单击列表中的任何项目时,它旁边的一个小PictureBox将显示相应文件的缩略图.我在
Windows 7上使用C#.
要获取缩略图,我已经重新发布到另一个问题中发布的方法.首先,我参考Windows API代码包.然后,我使用以下代码: ShellFile shellFile = ShellFile.FromFilePath(fullPathToFile); myPictureBox.Image = shellFile.Thumbnail.LargeBitmap; 这并不总是奏效有时,所示的缩略图只是“默认应用程序”图标.我发现,如果Windows以前生成了该文件的缩略图并将其存储在缩略图缓存中,则只会显示真实的缩略图.这意味着我必须手动打开一个文件夹,等待Windows为每个文件生成缩略图,然后我的应用程序将能够看到这些大拇指. 在使用Windows 7之前,我的程序如何强制Windows 7生成实际的缩略图? 更新(由Li0liQ) 可以通过添加FormatOption强制缩略图检索: ShellFile shellFile = ShellFile.FromFilePath(fullPathToFile); shellFile.Thumbnail.FormatOption = ShellThumbnailFormatOption.ThumbnailOnly; myPictureBox.Image = shellFile.Thumbnail.LargeBitmap; 但是,如果缩略图还没有,我会得到例外:
有关可能的线索,请参阅How do I refresh a file’s thumbnail in Windows Explorer?问题和代码snippet. 解决方法
这是一段代码,它提取缩略图位图(仅使用Windows Vista或更高版本).它基于酷
IShellItemImageFactory interface:
static void Main(string[] args) { // you can use any type of file supported by your windows installation. string path = @"c:tempwhatever.pdf"; using (Bitmap bmp = ExtractThumbnail(path,new Size(1024,1024),SIIGBF.SIIGBF_RESIZETOFIT)) { bmp.Save("whatever.png",ImageFormat.Png); } } public static Bitmap ExtractThumbnail(string filePath,Size size,SIIGBF flags) { if (filePath == null) throw new ArgumentNullException("filePath"); // TODO: you might want to cache the factory for different types of files // as this simple call may trigger some heavy-load underground operations IShellItemImageFactory factory; int hr = SHCreateItemFromParsingName(filePath,IntPtr.Zero,typeof(IShellItemImageFactory).GUID,out factory); if (hr != 0) throw new Win32Exception(hr); IntPtr bmp; hr = factory.GetImage(size,flags,out bmp); if (hr != 0) throw new Win32Exception(hr); return Bitmap.FromHbitmap(bmp); } [Flags] public enum SIIGBF { SIIGBF_RESIZETOFIT = 0x00000000,SIIGBF_BIGGERSIZEOK = 0x00000001,SIIGBF_MEMORYONLY = 0x00000002,SIIGBF_ICONONLY = 0x00000004,SIIGBF_THUMBNAILONLY = 0x00000008,SIIGBF_INCACHEONLY = 0x00000010,SIIGBF_CROPTOSQUARE = 0x00000020,SIIGBF_WIDETHUMBNAILS = 0x00000040,SIIGBF_ICONBACKGROUND = 0x00000080,SIIGBF_SCALEUP = 0x00000100,} [DllImport("shell32.dll",CharSet = CharSet.Unicode)] private static extern int SHCreateItemFromParsingName(string path,IntPtr pbc,[MarshalAs(UnmanagedType.LPStruct)] Guid riid,out IShellItemImageFactory factory); [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("bcc18b79-ba16-442f-80c4-8a59c30c463b")] private interface IShellItemImageFactory { [PreserveSig] int GetImage(Size size,SIIGBF flags,out IntPtr phbm); } 补充笔记: > GetImage方法有各种有趣的标志(SIIGBF),你可以玩.>出于性能原因,您可以缓存工厂.例如,.PDF文件要求整个Adobe Reader .exe在后台加载.>当与外壳(Windows资源管理器)通话时,您希望确保您的进程与shell的UAC级别相同,否则出于安全考虑,某些操作将失败.因此,例如,如果您在Visual Studio中从F5或CTRL F5运行流程,并且Visual Studio以管理员身份运行,则您的进程可能无法检索缩略图,而在双击.exe从探险家.在这些情况下,REGDB_E_CLASSNOTREG是一种典型的错误. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |