Note that there are some explanatory texts on larger screens.

plurals
  1. POCall to IExtractImage.GetLocation() is failing with NullReference Exception
    primarykey
    data
    text
    <p>I have the following code to import the IExtractImage interface.</p> <pre><code>[ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1")] public interface IExtractImage { [PreserveSig] Int32 GetLocation([MarshalAs(UnmanagedType.LPWStr)] out StringBuilder pszPathBuffer, int cch, ref int pdwPriority, SIZE prgSize, int dwRecClrDepth, ref int pdwFlags); [PreserveSig] Int32 Extract(out IntPtr phBmpThumbnail); } </code></pre> <p>I also have the IShellFolder imported, which I am not mentioning here for brevity. My intention is to access the thumbnail of a file using the shellfolder. So here's my code to retrieve the thumbnail. But my call to IExtractImage.GetLocation() is failing with a NullReference exception, stating</p> <p>"An exception of type 'System.NullReferenceException' occurred in CCDash.exe but was not handled in user code</p> <p>Additional information: Object reference not set to an instance of an object."</p> <p>Can someone please help me identify what is it that I am missing?</p> <pre><code>public Bitmap GetThumbNail(string mediaFileName) { IShellFolder shellDesktop; SHGetDesktopFolder(out shellDesktop); IntPtr pidlRoot; uint attribute = 0; string mediaPath = "C:\\Users\\&lt;user&gt;\\Videos"; // I have hard-coded the path for now uint pchEaten = 0; // Get the pidl of the media folder shellDesktop.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, mediaPath, ref pchEaten, out pidlRoot, ref attribute); Guid mediaFolderGuid = new Guid("000214E6-0000-0000-C000-000000000046"); shellDesktop.BindToObject(pidlRoot, IntPtr.Zero, mediaFolderGuid, out shellMediaFolder); IntPtr pidlMediaFolder; // Get the pidl of the media file shellMediaFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, mediaFileName, ref pchEaten, out pidlMediaFolder, ref attribute); Guid mediaFileImgGuid = new Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1"); uint rfgRes = 0; IExtractImage extractImage; shellMediaFolder.GetUIObjectOf(IntPtr.Zero, 1, out pidlMediaFolder, mediaFileImgGuid, ref rfgRes, out extractImage); SIZE size = new SIZE { cx = 40, cy = 40 }; int flags = 0x40 | 0x40; StringBuilder location = new StringBuilder(260, 260); int priority = 0; int requestedColourDepth = 0x20; IntPtr hBmp = IntPtr.Zero; // Now get the image extractImage.GetLocation(out location, location.Capacity, ref priority, size, requestedColourDepth, ref flags); extractImage.Extract(out hBmp); Bitmap thumbnail = Image.FromHbitmap(hBmp); return thumbnail; } </code></pre> <p>EDIT:</p> <p>I have now modified my code as below. Not very different from the first version, but with a little more error handling and better documentation and variable names that can help us understand my code better. Here's the modified code:</p> <pre><code>public Bitmap GetThumbNail(string mediaFileName) { Bitmap thumbnail = null; //Step 1: Use SHGetDesktopFolder to get the desktop folder. IShellFolder shellDesktop; SHGetDesktopFolder(out shellDesktop); if (shellDesktop != null) { IntPtr pidlMediaFolder; try { uint attribute = 0; string mediaPath = Path.GetDirectoryName(mediaFileName); uint pchEaten = 0; // Step 2: Using the desktop's IShellFolder, pass the file's parent folder path name into ParseDisplayName to get its PIDL. shellDesktop.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, mediaPath, ref pchEaten, out pidlMediaFolder, ref attribute); } catch (Exception) { Marshal.ReleaseComObject(shellDesktop); return null; } if (pidlMediaFolder != IntPtr.Zero) { Guid mediaFolderGuid = new Guid("000214E6-0000-0000-C000-000000000046"); IShellFolder shellMediaFolder; // Step 3: Using the desktop's IShellFolder, pass the PIDL into the BindToObject method // and get the IShellFolder interface of the file's parent folder. try { shellDesktop.BindToObject(pidlMediaFolder, IntPtr.Zero, mediaFolderGuid, out shellMediaFolder); } catch (Exception) { Marshal.ReleaseComObject(shellDesktop); return null; } if (shellMediaFolder != null) { IntPtr pidlMediaFile; uint attribute = 0; uint pchEaten = 0; // Step 4: Using the parent folder's IShellFolder, pass the file name into ParseDisplayName to get its PIDL. int ret = shellMediaFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, mediaFileName, ref pchEaten, out pidlMediaFile, ref attribute); Guid mediaFileImgGuid = new Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1"); uint rfgRes = 0; IExtractImage extractImage; // Step 5: Using the parent folder's IShellFolder, pass the file's PIDL // into the GetUIObjectOf. method to get the IExtractImage interface. ret = shellMediaFolder.GetUIObjectOf(IntPtr.Zero, 1, out pidlMediaFile, mediaFileImgGuid, ref rfgRes, out extractImage); SIZE size = new SIZE { cx = 40, cy = 40 }; uint flags = 0x0200; StringBuilder location = new StringBuilder(260, 260); int priority = 0; int requestedColourDepth = 0x20; IntPtr hBmp = IntPtr.Zero; // Now get the image extractImage.GetLocation(out location, location.Capacity, ref priority, size, requestedColourDepth, ref flags); extractImage.Extract(out hBmp); thumbnail = Image.FromHbitmap(hBmp); } } } return thumbnail; } </code></pre> <p>I see that at step 4, the pidlMediaFile is not retrieved correctly and it's value is still 0 after the ParseDisplayName() call. This is where the problem begins. I am not sure why the pidl for the filename is not retrieved whereas it is retrieved successfully for the file's parent folder.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload