2012-10-18 36 views
1

我有以下代碼來導入IExtractImage接口。調用IExtractImage.GetLocation()失敗,NullReference異常

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

我也有導入的IShellFolder,這裏我不提及它的簡潔。我的意圖是使用shell文件夾訪問文件的縮略圖。所以這裏是我的代碼來檢索縮略圖。但是我到IExtractImage.GetLocation()調用與NullReference異常失敗,說明

「類型‘System.NullReferenceException’的異常出現在CCDash.exe但在用戶代碼

其他信息沒有處理:你調用的對象是空的。」

有人能幫我找出我失蹤的是什麼嗎?

public Bitmap GetThumbNail(string mediaFileName) 
{ 
    IShellFolder shellDesktop; 
    SHGetDesktopFolder(out shellDesktop); 

    IntPtr pidlRoot; 
    uint attribute = 0; 
    string mediaPath = "C:\\Users\\<user>\\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; 
} 

編輯:

我現在已經如下修改我的代碼。與第一個版本沒什麼不同,但是多了一點錯誤處理和更好的文檔和變量名稱,可以幫助我們更好地理解我的代碼。這裏的修改後的代碼:

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

我看到,在步驟4中,pidlMediaFile不正確檢索和它的值仍爲0的ParseDisplayName()調用之後。這是問題開始的地方。我不知道爲什麼沒有檢索到文件名的pidl,而是爲文件的父文件夾成功檢索。

+0

看起來'extractImage'從'GetUIObjectOf()'返回'null'? –

+0

我同意。根據API調用爲什麼extractImage爲null會對你有什麼看起來很明顯嗎? – Mriganka

+0

'GetUiObjectOf()'返回一個'HRESULT'錯誤代碼。你可以檢查一下。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775073%28v=vs.85%29.aspx –

回答

0

看起來好像extractImage正在從GetUIObjectOf()返回null。嘗試檢查的HRESULT返回值,找出爲什麼null值正在返回。

編輯:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx

E_INVALIDARG One or more arguments are not valid 0x80070057 

根據該documentation,第三個參數是[in]參數,而不是一個[out]參數。

+0

我得到這個錯誤值:-2147024809(十六進制等同於FFFFFFFF80070057)。但是我沒有在任何地方找到這個錯誤代碼的任何定義。 – Mriganka

+0

現在,我不確定我是否按正確的順序使用正確的參數進行shell API調用。下面是我在做什麼: – Mriganka

+0

現在,我不確定我是否以正確的順序使用正確的參數進行shell API調用。這就是我所做的:1.獲取桌面的IShellFolder。 2.使用桌面文件夾獲取媒體文件夾的idl。 3.使用剛纔檢索到的idl獲取媒體文件夾的shell對象。 4.使用媒體文件夾的shell對象調用GetUIObjectOf()並傳遞剛纔檢索的idl。我在這個步驟列表中刪除了步驟shellMediaFolder.ParseDisplayName(),因爲這似乎是整個步驟序列中的不正確步驟。但是我仍然得到相同的錯誤。 – Mriganka