/// <summary> /// Gets an icons reource id if available in the format: /// "filename, index" /// where the first part is a string and the 2nd part is a negativ integer number). /// /// This format is usally used by the Windows Shell libraries so we use it here /// to add missing ResourceIds. /// </summary> /// <param name="parentIdList"></param> /// <param name="filename"></param> /// <param name="index"></param> /// <returns></returns> internal static bool GetIconResourceId(IdList parentIdList, out string filename, out int index) { filename = null; index = -1; IntPtr parentPtr = default(IntPtr); IntPtr relChildPtr = default(IntPtr); IntPtr ptrShellFolder = default(IntPtr); IntPtr ptrExtractIcon = default(IntPtr); IntPtr smallHicon = default(IntPtr); IntPtr largeHicon = default(IntPtr); try { if (parentIdList.Size == 0) { parentPtr = PidlManager.IdListToPidl(parentIdList); relChildPtr = PidlManager.IdListToPidl(IdList.Create()); } else { IdList parIdList = null, relChildIdList = null; PidlManager.GetParentChildIdList(parentIdList, out parIdList, out relChildIdList); parentPtr = PidlManager.IdListToPidl(parIdList); relChildPtr = PidlManager.IdListToPidl(relChildIdList); } if (parentPtr == default(IntPtr) || relChildPtr == default(IntPtr)) { return(false); } Guid guid = typeof(IShellFolder2).GUID; HRESULT hr = NativeMethods.SHBindToParent(parentPtr, guid, out ptrShellFolder, ref relChildPtr); if (hr != HRESULT.S_OK) { return(false); } using (var shellFolder = new ShellFolder(ptrShellFolder)) { if (shellFolder == null) { return(false); } guid = typeof(IExtractIcon).GUID; var pidls = new IntPtr[] { relChildPtr }; hr = shellFolder.Obj.GetUIObjectOf(IntPtr.Zero, 1, pidls, guid, IntPtr.Zero, out ptrExtractIcon); if (hr != HRESULT.S_OK) { return(false); } using (var extractIcon = new GenericCOMFolder <IExtractIcon>(ptrExtractIcon)) { if (extractIcon == null) { return(false); } var iconFile = new StringBuilder(NativeMethods.MAX_PATH); uint pwFlags = 0; hr = extractIcon.Obj.GetIconLocation(0, iconFile, (uint)iconFile.Capacity, ref index, ref pwFlags); if (hr != HRESULT.S_OK) { return(false); } if (string.IsNullOrEmpty(iconFile.ToString())) { return(false); } filename = iconFile.ToString(); return(true); } } } finally { if (parentPtr != default(IntPtr)) { NativeMethods.ILFree(parentPtr); } ////if (relChildPtr != default(IntPtr)) //// Shell32.ILFree(relChildPtr); if (smallHicon != default(IntPtr)) { NativeMethods.DestroyIcon(smallHicon); } if (largeHicon != default(IntPtr)) { NativeMethods.DestroyIcon(largeHicon); } } }