C # получить эскиз из файла через windows api
Проводник Windows имеет возможность показывать миниатюры файлов. Эти миниатюры предоставляются расширениями ядра и сторонних оболочек.
Я знаю, как расширить оболочку для предоставления эскизов Windows.
То, что я хочу сделать, – это извлечь эскиз из любого файла в системе через оболочку с помощью C #. Это возможно?
- Отправка ключа Windows с помощью SendKeys
- Как предотвратить GCC от оптимизации цикла ожидания занятости?
- Делает ли система волатильностью все ее члены неустойчивыми?
- Оптимальный способ чтения файла Excel (.xls / .xlsx)
- Пользовательский блок сообщений
По сути, я пишу пользовательский файловый браузер, и я хочу показывать эскизы и не могу разобрать каждый файл на планете, чтобы сделать мои собственные миниатюры.
Уточнение. Многие ответы, похоже, сосредоточены вокруг миниатюр веб-страниц или масштабирования изображения. Но это совсем не то, что я ищу. Я хочу спросить Windows о представлении миниатюр этих типов файлов: .DOC, .PDF, .3DM, .DWG … и mabye еще около десятка. Я не хочу анализировать, визуализировать и создавать миниатюры самостоятельно, потому что Windows уже знает, как это сделать.
Код, который я написал как ответ, действительно работает … возможно, его можно упростить и немного почистить.
- Рекурсивное объявление указателя функции в C
- Многопоточный рендеринг на OpenGL
- Как принудительно распространять изменения роли для пользователей с помощью ASP.NET Identity 2.0.1?
- Как добавить новую строку в txt-файл
- Объединение нескольких текстовых документов в один Open Xml
- Можно ли перебирать аргументы в переменных массивах?
- Как писать на страницу OneNote 2013 с использованием C # и OneNote Interop
- Почему fork () дважды
Пробежал через это сегодня – ему уже несколько месяцев, но для меня это сделало для меня (на Win7, извлечение миниатюр в файлах MPEG-4):
- Источник: https://github.com/dbarros/WindowsAPICodePack
- Nuget: https://www.nuget.org/packages/WindowsAPICodePack-Shell
Код:
ShellFile shellFile = ShellFile.FromFilePath(pathToYourFile); Bitmap shellThumb = shellFile.Thumbnail.ExtraLargeBitmap;
Надеюсь, поможет!
Миниатюры Microsoft Office в SharePoint по адресу http://msdn.microsoft.com/en-us/library/aa289172(VS.71).aspx . это именно то, что вы хотите. (Мне не удалось преобразовать код VB.NET в C #, используя http://www.developerfusion.com/tools/convert/vb-to-csharp/ .)
Что касается кода, который вы отправили в своем ответе, извлечение эскизов с помощью командной оболочки по адресу http://www.vbaccelerator.com/home/net/code/libraries/Shell_Projects/Thumbnail_Extraction/article.asp – это оригинальная статья, из которой код. Я считаю, что почти все образцы IExtractImage
(вы находите поиск) основаны на коде этой статьи из-за соглашения об именах, комментариев и т. Д., Которые переносятся из оригинала. Поскольку эта статья датируется апрелем 2003 года, она содержит некоторые нестандартные (не.NET) соглашения о кодировании. Я провел базовое тестирование, а также проблемы сбора мусора, освобождение неуправляемых ресурсов и другие проблемы с очисткой. Поэтому я настоятельно рекомендую избегать кода в этой статье. Более того, код структурирован, так что это затрудняет техническое обслуживание.
Существует чистая упрощенная версия MSDN от июля 2005 года под названием Microsoft Office Thumbnails в SharePoint по адресу http://msdn.microsoft.com/en-us/library/aa289172(VS.71).aspx . Этот код и код статьи имеют сходство, что заставляет меня думать, что извлечение эскизов с использованием статьи оболочки является основой для статьи SharePoint . Версия GetThumbnailImage
версии VB.NET игнорирует параметр longestEdge
, но версия C ++ использует его и документирует использование ORIGSIZE
и QUALITY
. Кроме того, код иллюстрирует использование .NET FreeCoTaskMem
вместо FreeCoTaskMem
Shell и SHGetMalloc
.
IExtractImage
работает с файлами, папками и другими объектами пространства имен. Код MSDN работает со скрытыми файлами, тогда как для кода vbAccelerator необходимо добавить EnumObjects
вызов EnumObjects
. Кроме того, vbAccelerator перечисляет объекты оболочки, которые ищут указанный файл, что кажется пустой тратой времени. Возможно, это было необходимо для поиска правильного «относительного» PIDL, который используется для вызова GetUIObjectOf
.
ShellThumbnail (Незавершенное производство)
Полный образец проекта по адресу http://cid-7178d2c79ba0a7e3.office.live.com/self.aspx/.Public/ShellThumbnail.zip .
Imports System.Runtime.InteropServices Namespace Shell '''
''' Generates a thumbnail of a folder's picture or a file's image. ''' '''This is the "Folder's Picture" and not the "Folder's Icon"! Use SHGetFileInfo to generate the thumbnail for a folder's icon or for a file that does not have a thumbnail handler. '''Microsoft Office Thumbnails in SharePoint at http://msdn.microsoft.com/en-us/library/aa289172%28VS.71%29.aspx. Public Class ShellThumbnail 'TODO - Work out the details for image size and IEIFLAG handling. #Region " Determining Thumbnail Size and Quality [documentation] " 'http://support.microsoft.com/kb/835823 'Determining Thumbnail Size and Quality 'Browse to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer. Create or modify two DWORDs called ThumbnailSize and ThumbnailQuality. For ThumbnailSize set the value in pixels, with the default being 96. For ThumbnailQuality set the value as a number that represents the percentage quality between 50 and 100. 'http://www.pctools.com/guides/registry/detail/1066/ (modified) ' User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer] 'System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer] 'Value Name: ThumbnailSize, ThumbnailQuality ' Data Type: REG_DWORD (DWORD Value) 'Value Data: Size in pixels (32-255), Quality Percentage (50-100) 'Microsoft® Windows® XP Registry Guide 'Jerry Honeycutt '09/11/2002 'Microsoft Press 'http://www.microsoft.com/mspress/books/sampchap/6232.aspx#118 'Thumbnails
The Thumbnails category controls the 'quality of thumbnails in Windows Explorer. Table 5-10 describes the values for 'Image Quality and Size. Create values that you don't see in the registry. The 'default value forThumbnailQuality
is0x5A
. The 'default value forThumbnailSize
is0x60
. Keep in mind 'that higher quality and larger thumbnails require more disk space, which is not 'usually a problem, but they also take longer to display. Changing the quality 'does not affect thumbnails that already exist on the file system. 'Table 5-10 Values in Thumbnails '
'
Setting | 'Name | 'Type | 'Data |
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer | '' | ' | |
Image Quality | 'ThumbnailQuality | 'REG_DWORD | '0x32 - 0x64 |
Size (pixels) | 'ThumbnailSize | 'REG_DWORD | '0x20 - 0xFF |
Imports System.Runtime.InteropServices Namespace Shell ''' ''' Generates a thumbnail of a folder's picture or a file's image. ''' ''' This is the "Folder's Picture" and not the "Folder's Icon"! Use SHGetFileInfo to generate the thumbnail for a folder's icon or for a file that does not have a thumbnail handler. ''' Microsoft Office Thumbnails in SharePoint at http://msdn.microsoft.com/en-us/library/aa289172%28VS.71%29.aspx. Public Class ShellThumbnail 'TODO - Work out the details for image size and IEIFLAG handling. #Region " Determining Thumbnail Size and Quality [documentation] " 'http://support.microsoft.com/kb/835823 'Determining Thumbnail Size and Quality 'Browse to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer. Create or modify two DWORDs called ThumbnailSize and ThumbnailQuality. For ThumbnailSize set the value in pixels, with the default being 96. For ThumbnailQuality set the value as a number that represents the percentage quality between 50 and 100. 'http://www.pctools.com/guides/registry/detail/1066/ (modified) ' User Key: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer] 'System Key: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer] 'Value Name: ThumbnailSize, ThumbnailQuality ' Data Type: REG_DWORD (DWORD Value) 'Value Data: Size in pixels (32-255), Quality Percentage (50-100) 'Microsoft® Windows® XP Registry Guide 'Jerry Honeycutt '09/11/2002 'Microsoft Press 'http://www.microsoft.com/mspress/books/sampchap/6232.aspx#118 'Thumbnails
The Thumbnails category controls the 'quality of thumbnails in Windows Explorer. Table 5-10 describes the values for 'Image Quality and Size. Create values that you don't see in the registry. The 'default value for
ThumbnailQuality
is 0x5A
. The 'default value for ThumbnailSize
is 0x60
. Keep in mind 'that higher quality and larger thumbnails require more disk space, which is not 'usually a problem, but they also take longer to display. Changing the quality 'does not affect thumbnails that already exist on the file system. 'Table 5-10 Values in Thumbnails '
'
Setting | 'Name | 'Type | 'Data |
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer | '' | ' | |
Image Quality | 'ThumbnailQuality | 'REG_DWORD | '0x32 - 0x64 |
Size (pixels) | 'ThumbnailSize | 'REG_DWORD | '0x20 - 0xFF |
Это может помочь:
Это включает в себя Shell API и позволяет делать практически все, что может использовать shell (включая рендеринг эскизов).
Вот class, который я нашел в Интернете. Похоже, что исходный код получен из http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21789724.html , но я не вижу его, чтобы дать правильную атрибуцию. Я нашел источник здесь: http://www.vbforums.com/showthread.php?t=527704
Вот class с соответствующими COM-вызовами, воспроизведенными здесь для потомков:
using System; using System.Diagnostics; using System.Drawing; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace RMA.Shell { public class ShellThumbnail : IDisposable { [Flags] private enum ESTRRET { STRRET_WSTR = 0, STRRET_OFFSET = 1, STRRET_CSTR = 2 } [Flags] private enum ESHCONTF { SHCONTF_FOLDERS = 32, SHCONTF_NONFOLDERS = 64, SHCONTF_INCLUDEHIDDEN = 128, } [Flags] private enum ESHGDN { SHGDN_NORMAL = 0, SHGDN_INFOLDER = 1, SHGDN_FORADDRESSBAR = 16384, SHGDN_FORPARSING = 32768 } [Flags] private enum ESFGAO { SFGAO_CANCOPY = 1, SFGAO_CANMOVE = 2, SFGAO_CANLINK = 4, SFGAO_CANRENAME = 16, SFGAO_CANDELETE = 32, SFGAO_HASPROPSHEET = 64, SFGAO_DROPTARGET = 256, SFGAO_CAPABILITYMASK = 375, SFGAO_LINK = 65536, SFGAO_SHARE = 131072, SFGAO_READONLY = 262144, SFGAO_GHOSTED = 524288, SFGAO_DISPLAYATTRMASK = 983040, SFGAO_FILESYSANCESTOR = 268435456, SFGAO_FOLDER = 536870912, SFGAO_FILESYSTEM = 1073741824, SFGAO_HASSUBFOLDER = -2147483648, SFGAO_CONTENTSMASK = -2147483648, SFGAO_VALIDATE = 16777216, SFGAO_REMOVABLE = 33554432, SFGAO_COMPRESSED = 67108864, } private enum EIEIFLAG { IEIFLAG_ASYNC = 1, IEIFLAG_CACHE = 2, IEIFLAG_ASPECT = 4, IEIFLAG_OFFLINE = 8, IEIFLAG_GLEAM = 16, IEIFLAG_SCREEN = 32, IEIFLAG_ORIGSIZE = 64, IEIFLAG_NOSTAMP = 128, IEIFLAG_NOBORDER = 256, IEIFLAG_QUALITY = 512 } [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 0, CharSet = CharSet.Auto)] private struct STRRET_CSTR { public ESTRRET uType; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 520)] public byte[] cStr; } [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)] private struct STRRET_ANY { [FieldOffset(0)] public ESTRRET uType; [FieldOffset(4)] public IntPtr pOLEString; } [StructLayoutAttribute(LayoutKind.Sequential)] private struct SIZE { public int cx; public int cy; } [ComImport(), Guid("00000000-0000-0000-C000-000000000046")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IUnknown { [PreserveSig()] IntPtr QueryInterface(ref Guid riid, ref IntPtr pVoid); [PreserveSig()] IntPtr AddRef(); [PreserveSig()] IntPtr Release(); } [ComImportAttribute()] [GuidAttribute("00000002-0000-0000-C000-000000000046")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] private interface IMalloc { [PreserveSig()] IntPtr Alloc(int cb); [PreserveSig()] IntPtr Realloc(IntPtr pv, int cb); [PreserveSig()] void Free(IntPtr pv); [PreserveSig()] int GetSize(IntPtr pv); [PreserveSig()] int DidAlloc(IntPtr pv); [PreserveSig()] void HeapMinimize(); } [ComImportAttribute()] [GuidAttribute("000214F2-0000-0000-C000-000000000046")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] private interface IEnumIDList { [PreserveSig()] int Next(int celt, ref IntPtr rgelt, ref int pceltFetched); void Skip(int celt); void Reset(); void Clone(ref IEnumIDList ppenum); } [ComImportAttribute()] [GuidAttribute("000214E6-0000-0000-C000-000000000046")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] private interface IShellFolder { void ParseDisplayName(IntPtr hwndOwner, IntPtr pbcReserved, [MarshalAs(UnmanagedType.LPWStr)]string lpszDisplayName, ref int pchEaten, ref IntPtr ppidl, ref int pdwAttributes); void EnumObjects(IntPtr hwndOwner, [MarshalAs(UnmanagedType.U4)]ESHCONTF grfFlags, ref IEnumIDList ppenumIDList); void BindToObject(IntPtr pidl, IntPtr pbcReserved, ref Guid riid, ref IShellFolder ppvOut); void BindToStorage(IntPtr pidl, IntPtr pbcReserved, ref Guid riid, IntPtr ppvObj); [PreserveSig()] int CompareIDs(IntPtr lParam, IntPtr pidl1, IntPtr pidl2); void CreateViewObject(IntPtr hwndOwner, ref Guid riid, IntPtr ppvOut); void GetAttributesOf(int cidl, IntPtr apidl, [MarshalAs(UnmanagedType.U4)]ref ESFGAO rgfInOut); void GetUIObjectOf(IntPtr hwndOwner, int cidl, ref IntPtr apidl, ref Guid riid, ref int prgfInOut, ref IUnknown ppvOut); void GetDisplayNameOf(IntPtr pidl, [MarshalAs(UnmanagedType.U4)]ESHGDN uFlags, ref STRRET_CSTR lpName); void SetNameOf(IntPtr hwndOwner, IntPtr pidl, [MarshalAs(UnmanagedType.LPWStr)]string lpszName, [MarshalAs(UnmanagedType.U4)] ESHCONTF uFlags, ref IntPtr ppidlOut); } [ComImportAttribute(), GuidAttribute("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] private interface IExtractImage { void GetLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszPathBuffer, int cch, ref int pdwPriority, ref SIZE prgSize, int dwRecClrDepth, ref int pdwFlags); void Extract(ref IntPtr phBmpThumbnail); } private class UnmanagedMethods { [DllImport("shell32", CharSet = CharSet.Auto)] internal extern static int SHGetMalloc(ref IMalloc ppMalloc); [DllImport("shell32", CharSet = CharSet.Auto)] internal extern static int SHGetDesktopFolder(ref IShellFolder ppshf); [DllImport("shell32", CharSet = CharSet.Auto)] internal extern static int SHGetPathFromIDList(IntPtr pidl, StringBuilder pszPath); [DllImport("gdi32", CharSet = CharSet.Auto)] internal extern static int DeleteObject(IntPtr hObject); } ~ShellThumbnail() { Dispose(); } private IMalloc alloc = null; private bool disposed = false; private Size _desiredSize = new Size(100, 100); private Bitmap _thumbNail; public Bitmap ThumbNail { get { return _thumbNail; } } public Size DesiredSize { get { return _desiredSize; } set { _desiredSize = value; } } private IMalloc Allocator { get { if (!disposed) { if (alloc == null) { UnmanagedMethods.SHGetMalloc(ref alloc); } } else { Debug.Assert(false, "Object has been disposed."); } return alloc; } } public Bitmap GetThumbnail(string fileName) { if (string.IsNullOrEmpty(fileName)) return null; if (!File.Exists(fileName) && !Directory.Exists(fileName)) { throw new FileNotFoundException(string.Format("The file '{0}' does not exist", fileName), fileName); } if (_thumbNail != null) { _thumbNail.Dispose(); _thumbNail = null; } IShellFolder folder = null; try { folder = getDesktopFolder; } catch (Exception ex) { throw ex; } if (folder != null) { IntPtr pidlMain = IntPtr.Zero; try { int cParsed = 0; int pdwAttrib = 0; string filePath = Path.GetDirectoryName(fileName); folder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, filePath, ref cParsed, ref pidlMain, ref pdwAttrib); } catch (Exception ex) { Marshal.ReleaseComObject(folder); throw ex; } if (pidlMain != IntPtr.Zero) { Guid iidShellFolder = new Guid("000214E6-0000-0000-C000-000000000046"); IShellFolder item = null; try { folder.BindToObject(pidlMain, IntPtr.Zero, ref iidShellFolder, ref item); } catch (Exception ex) { Marshal.ReleaseComObject(folder); Allocator.Free(pidlMain); throw ex; } if (item != null) { IEnumIDList idEnum = null; try { item.EnumObjects(IntPtr.Zero, (ESHCONTF.SHCONTF_FOLDERS | ESHCONTF.SHCONTF_NONFOLDERS), ref idEnum); } catch (Exception ex) { Marshal.ReleaseComObject(folder); Allocator.Free(pidlMain); throw ex; } if (idEnum != null) { int hRes = 0; IntPtr pidl = IntPtr.Zero; int fetched = 0; bool complete = false; while (!complete) { hRes = idEnum.Next(1, ref pidl, ref fetched); if (hRes != 0) { pidl = IntPtr.Zero; complete = true; } else { if (_getThumbNail(fileName, pidl, item)) { complete = true; } } if (pidl != IntPtr.Zero) { Allocator.Free(pidl); } } Marshal.ReleaseComObject(idEnum); } Marshal.ReleaseComObject(item); } Allocator.Free(pidlMain); } Marshal.ReleaseComObject(folder); } return ThumbNail; } private bool _getThumbNail(string file, IntPtr pidl, IShellFolder item) { IntPtr hBmp = IntPtr.Zero; IExtractImage extractImage = null; try { string pidlPath = PathFromPidl(pidl); if (Path.GetFileName(pidlPath).ToUpper().Equals(Path.GetFileName(file).ToUpper())) { IUnknown iunk = null; int prgf = 0; Guid iidExtractImage = new Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1"); item.GetUIObjectOf(IntPtr.Zero, 1, ref pidl, ref iidExtractImage, ref prgf, ref iunk); extractImage = (IExtractImage)iunk; if (extractImage != null) { Console.WriteLine("Got an IExtractImage object!"); SIZE sz = new SIZE(); sz.cx = DesiredSize.Width; sz.cy = DesiredSize.Height; StringBuilder location = new StringBuilder(260, 260); int priority = 0; int requestedColourDepth = 32; EIEIFLAG flags = EIEIFLAG.IEIFLAG_ASPECT | EIEIFLAG.IEIFLAG_SCREEN; int uFlags = (int)flags; try { extractImage.GetLocation(location, location.Capacity, ref priority, ref sz, requestedColourDepth, ref uFlags); extractImage.Extract(ref hBmp); } catch (System.Runtime.InteropServices.COMException ex) { } if (hBmp != IntPtr.Zero) { _thumbNail = Bitmap.FromHbitmap(hBmp); } Marshal.ReleaseComObject(extractImage); extractImage = null; } return true; } else { return false; } } catch (Exception ex) { if (hBmp != IntPtr.Zero) { UnmanagedMethods.DeleteObject(hBmp); } if (extractImage != null) { Marshal.ReleaseComObject(extractImage); } throw ex; } } private string PathFromPidl(IntPtr pidl) { StringBuilder path = new StringBuilder(260, 260); int result = UnmanagedMethods.SHGetPathFromIDList(pidl, path); if (result == 0) { return string.Empty; } else { return path.ToString(); } } private IShellFolder getDesktopFolder { get { IShellFolder ppshf = null; int r = UnmanagedMethods.SHGetDesktopFolder(ref ppshf); return ppshf; } } public void Dispose() { if (!disposed) { if (alloc != null) { Marshal.ReleaseComObject(alloc); } alloc = null; if (_thumbNail != null) { _thumbNail.Dispose(); } disposed = true; } } } }
К сожалению, к сожалению, к ним не относятся мини-эскизы окон API-интерфейса Windows API.
Не совсем то, что вы просили, но вот проект для открытия файла Thumbs.db .
Статья в Википедии содержит дополнительную информацию о том, где найти миниатюры в Vista & 7.
Вы должны использовать windows GDI + для получения этих миниатюр, например.