ruta obtener nombre manipular fecha directorios directorio creación creacion carpeta buscar archivos archivo c# windows-shell
http://cid-7178d2c79ba0a7e3.office.live.com/self.aspx/.Public/ShellThumbnail.zip

nombre - C#obtener una miniatura del archivo a través de la API de Windows



obtener ruta de carpeta c# (7)

El explorador de Windows tiene la capacidad de mostrar miniaturas de archivos. Estas miniaturas son provistas por extensiones de shell de núcleo y de terceros.

Sé cómo extender el shell para proporcionar miniaturas a Windows.

Lo que quiero hacer es recuperar la imagen en miniatura de cualquier archivo en el sistema a través del shell usando C #. es posible?

Básicamente, estoy escribiendo un explorador de archivos personalizado y quiero mostrar miniaturas, y no puedo analizar todos los archivos del planeta para hacer mis propias miniaturas.

Aclaración: muchas respuestas parecen centrarse en las miniaturas de la página web o escalar una imagen. Pero eso no es todo lo que estoy buscando. Lo que quiero es pedirle a Windows la representación en miniatura de estos tipos de archivos: .DOC, .PDF, .3DM, .DWG ... y mabye una docena más. No quiero analizar, renderizar y crear miniaturas personalmente, porque Windows ya sabe cómo hacerlo.

El código que publiqué como respuesta realmente funciona ... quizás se pueda simplificar y limpiar un poco.


Aquí hay una clase que encontré buscando en Internet. Parece que el código original provino de http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21789724.html , pero no puedo verlo para dar la atribución adecuada. Encontré la fuente aquí: http://www.vbforums.com/showthread.php?t=527704

Aquí hay una clase con las llamadas COM correctas, reproducidas aquí para la posteridad:

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; } } } }


Debe usar Windows GDI + para obtener estas miniaturas, así.


Desafortunadamente, XP / 2003 no admite las llamadas en miniatura del paquete de códigos de la API de Windows.





Miniaturas de Microsoft Office en SharePoint en http://msdn.microsoft.com/en-us/library/aa289172(VS.71).aspx . es exactamente lo que quieres (No tuve problemas para convertir el código VB.NET en C # usando http://www.developerfusion.com/tools/convert/vb-to-csharp/ .)

Con respecto al código que publicó en su respuesta, Extracción de miniaturas utilizando el Shell en http://www.vbaccelerator.com/home/net/code/libraries/Shell_Projects/Thumbnail_Extraction/article.asp es el artículo original del que es el código. Creo que casi todos los ejemplos de IExtractImage (se encuentra buscando) se basan en el código de este artículo, debido a convenciones de nombres, comentarios, etc., que se llevan del original. Dado que este artículo data de abril de 2003, contiene algunas convenciones de codificación no estándar (no de .NET). Hice algunas pruebas básicas, y hay problemas de recolección de basura, liberando problemas de recursos no administrados y otros problemas de limpieza. Por lo tanto, hago una fuerte recomendación para evitar el código en ese artículo. Además, el código está estructurado de tal manera que dificulta el mantenimiento.

Hay una versión simplier más limpia en MSDN, con fecha de julio de 2005, llamada Miniaturas de Microsoft Office en SharePoint en http://msdn.microsoft.com/en-us/library/aa289172(VS.71).aspx . Este código y el código del artículo comparten similitudes, lo que me lleva a pensar que la extracción de miniaturas utilizando el artículo de Shell es la base del artículo de SharePoint . La versión VB.NET de GetThumbnailImage ignora el parámetro longestEdge , pero la versión C ++ lo usa y documenta el uso de los ORIGSIZE y QUALITY . Además, el código ilustra cómo usar FreeCoTaskMem de .NET en lugar de IMalloc y SHGetMalloc .

IExtractImage funciona con archivos, carpetas y otros objetos de espacio de nombres. El código MSDN funciona con archivos ocultos, mientras que el código vbAccelerator necesita SHCONTF_INCLUDEHIDDEN agregado a la llamada EnumObjects . Además, vbAccelerator enumera los objetos de la carpeta del shell que buscan el archivo especificado, lo que parece una pérdida de tiempo. Esto puede haber sido necesario para encontrar el PIDL "relativo" correcto que se utiliza para la llamada GetUIObjectOf .

ShellThumbnail (Trabajo en progreso)

Proyecto de ejemplo completo en http://cid-7178d2c79ba0a7e3.office.live.com/self.aspx/.Public/ShellThumbnail.zip .

Imports System.Runtime.InteropServices Namespace Shell '''''' <summary> '''''' Generates a thumbnail of a folder''s picture or a file''s image. '''''' </summary> '''''' <remarks>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.</remarks> '''''' <reference>Microsoft Office Thumbnails in SharePoint at http://msdn.microsoft.com/en-us/library/aa289172%28VS.71%29.aspx.</reference> 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 ''<H3><I><A name=118></A>Thumbnails</I></H3>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 <CODE>ThumbnailQuality</CODE> is <CODE>0x5A</CODE>. The ''default value for <CODE>ThumbnailSize</CODE> is <CODE>0x60</CODE>. 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. ''<P><B>Table 5-10 </B><I>Values in Thumbnails</I> ''<P> ''<TABLE border=0 cellSpacing=1 cellPadding=4 width="100%"> ''<TBODY> ''<TR> ''<TD bgColor=#999999 vAlign=top><B>Setting</B></TD> ''<TD bgColor=#999999 vAlign=top><B>Name</B></TD> ''<TD bgColor=#999999 vAlign=top><B>Type</B></TD> ''<TD bgColor=#999999 vAlign=top><B>Data</B></TD></TR> ''<TR> ''<TD bgColor=#cccccc ''vAlign=top><CODE><B>HKCU/Software/Microsoft/Windows/CurrentVersion/Explorer</B></CODE></TD> ''<TD bgColor=#cccccc vAlign=top> </TD> ''<TD bgColor=#cccccc vAlign=top> </TD> ''<TD bgColor=#cccccc vAlign=top> </TD></TR> ''<TR> ''<TD bgColor=#cccccc vAlign=top><CODE>Image Quality</CODE></TD> ''<TD bgColor=#cccccc vAlign=top><CODE>ThumbnailQuality</CODE></TD> ''<TD bgColor=#cccccc vAlign=top><CODE>REG_DWORD</CODE></TD> ''<TD bgColor=#cccccc vAlign=top><CODE>0x32 - 0x64</CODE></TD></TR> ''<TR> ''<TD bgColor=#cccccc vAlign=top><CODE>Size (pixels)</CODE></TD> ''<TD bgColor=#cccccc vAlign=top><CODE>ThumbnailSize</CODE></TD> ''<TD bgColor=#cccccc vAlign=top><CODE>REG_DWORD</CODE></TD> ''<TD bgColor=#cccccc vAlign=top><CODE>0x20 - 0xFF</CODE></TD></TR></TBODY></TABLE></P> #End Region Public Shared ReadOnly DefaultThumbnailSize As New System.Drawing.Size(96, 96) Public Const DefaultColorDepth As Integer = 32 '''''' <summary> '''''' Used to request an image from an object, such as an item in a Shell folder. '''''' </summary> '''''' <param name="path">An absolute path to a file or folder.</param> Public Shared Function ExtractImage(ByVal path As String) As Bitmap Return ExtractImage(path, System.Drawing.Size.Empty, DefaultColorDepth, 0) End Function '''''' <summary> '''''' Used to request an image from an object, such as an item in a Shell folder. '''''' </summary> '''''' <param name="path">An absolute path to a file or folder.</param> '''''' <param name="size"></param> Public Shared Function ExtractImage(ByVal path As String, ByVal size As System.Drawing.Size) As Bitmap Return ExtractImage(path, size, DefaultColorDepth, 0) End Function '''''' <summary> '''''' Used to request an image from an object, such as an item in a Shell folder. '''''' </summary> '''''' <param name="path">An absolute path to a file or folder.</param> '''''' <param name="size"></param> '''''' <param name="recommendedColorDepth">The recommended color depth in units of bits per pixel. The default is 32.</param> Public Shared Function ExtractImage(ByVal path As String, ByVal size As System.Drawing.Size, ByVal recommendedColorDepth As Integer) As Bitmap Return ExtractImage(path, size, recommendedColorDepth, 0) End Function '''''' <summary> '''''' Used to request an image from an object, such as an item in a Shell folder. '''''' </summary> '''''' <param name="path">An absolute path to a file or folder.</param> '''''' <param name="size"></param> '''''' <param name="recommendedColorDepth">The recommended color depth in units of bits per pixel. The default is 32.</param> Private Shared Function ExtractImage(ByVal path As String, ByVal size As System.Drawing.Size, ByVal recommendedColorDepth As Integer, ByVal flags As IEIFLAG) As Bitmap Dim oResult As Bitmap = Nothing Dim oDesktopFolder As IShellFolder = Nothing Dim hParentIDL As IntPtr Dim hIDL As IntPtr Dim oParentFolder As IShellFolder Dim hParentFolder As IntPtr Dim oExtractImage As IExtractImage Dim hExtractImage As IntPtr ''Divide the file name into a path and file/folder name. Dim sFolderName As String = System.IO.Path.GetDirectoryName(path) Dim sBaseName As String = System.IO.Path.GetFileName(path) ''Get the desktop IShellFolder. If SHGetDesktopFolder(oDesktopFolder) <> Missico.Win32.S_OK Then Throw New System.Runtime.InteropServices.COMException End If ''Get the parent folder for the specified path. oDesktopFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, sFolderName, 0, hParentIDL, 0) oDesktopFolder.BindToObject(hParentIDL, IntPtr.Zero, ShellGUIDs.IID_IShellFolder, hParentFolder) oParentFolder = CType(Marshal.GetTypedObjectForIUnknown(hParentFolder, GetType(IShellFolder)), IShellFolder) ''Get the file/folder''s IExtractImage oParentFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, sBaseName, 0, hIDL, 0) oParentFolder.GetUIObjectOf(IntPtr.Zero, 1, New IntPtr() {hIDL}, ShellGUIDs.IID_IExtractImage, IntPtr.Zero, hExtractImage) ''Free the pidls. The Runtime Callable Wrappers (RCW) should automatically release the COM objects. Marshal.FreeCoTaskMem(hParentIDL) Marshal.FreeCoTaskMem(hIDL) Marshal.FinalReleaseComObject(oParentFolder) Marshal.FinalReleaseComObject(oDesktopFolder) If hExtractImage = IntPtr.Zero Then ''There is no handler for this file, which is odd. I believe we should default the file''s type icon. Debug.WriteLine(String.Format("There is no thumbnail for the specified file ''{0}''.", path), "ShellThumbnail.ExtractImage") Else oExtractImage = CType(Marshal.GetTypedObjectForIUnknown(hExtractImage, GetType(IExtractImage)), IExtractImage) ''Set the size and flags Dim oSize As Missico.Win32.SIZE ''must specify a size Dim iFlags As IEIFLAG = flags Or IEIFLAG.IEIFLAG_ORIGSIZE Or IEIFLAG.IEIFLAG_QUALITY Or IEIFLAG.IEIFLAG_ASPECT If size.IsEmpty Then oSize.cx = DefaultThumbnailSize.Width oSize.cy = DefaultThumbnailSize.Height Else oSize.cx = size.Width oSize.cy = size.Height End If Dim hBitmap As IntPtr Dim sPath As New System.Text.StringBuilder(Missico.Win32.MAX_PATH, Missico.Win32.MAX_PATH) oExtractImage.GetLocation(sPath, sPath.Capacity, 0, oSize, recommendedColorDepth, iFlags) ''if the specified path is to a folder then IExtractImage.Extract fails. Try oExtractImage.Extract(hBitmap) Catch ex As System.Runtime.InteropServices.COMException ''clear the handle since extract failed hBitmap = IntPtr.Zero Debug.WriteLine(String.Format("There is no thumbnail for the specified folder ''{0}''.", path), "ShellThumbnail.ExtractImage") Finally Marshal.FinalReleaseComObject(oExtractImage) End Try If Not hBitmap.Equals(IntPtr.Zero) Then ''create the image from the handle oResult = System.Drawing.Bitmap.FromHbitmap(hBitmap) ''dump the properties to determine what kind of bitmap is returned ''Missico.Diagnostics.ObjectDumper.Write(oResult) ''Tag={ } ''PhysicalDimension={Width=96, Height=96} ''Size={Width=96, Height=96} ''Width=96 ''Height=96 ''HorizontalResolution=96 ''VerticalResolution=96 ''Flags=335888 ''RawFormat={ } ''PixelFormat=Format32bppRgb ''Palette={ } ''FrameDimensionsList=... ''PropertyIdList=... ''PropertyItems=... Missico.Win32.DeleteObject(hBitmap) ''release the handle End If End If Return oResult End Function End Class End Namespace