/// <summary> /// Constructor. Create a sub-item shell item object. /// </summary> /// <param name="shDesktop">IShellFolder interface of the Desktop</param> /// <param name="pIDL">The fully qualified PIDL for this shell item</param> /// <param name="shParent">The ShellItem object for this item's parent</param> public ShellItem(ShellAPI.IShellFolder shDesktop, IntPtr pIDL, ShellItem shParent) { // We need the Desktop shell item to exist first. if (m_bHaveRootShell == false) { throw new Exception("The root shell item must be created before creating a sub-item"); } // Create the FQ PIDL for this new item. m_pIDL = ShellAPI.ILCombine(shParent.PIDL, pIDL); // Get the properties of this item. ShellAPI.SFGAOF uFlags = ShellAPI.SFGAOF.SFGAO_FOLDER | ShellAPI.SFGAOF.SFGAO_HASSUBFOLDER; // Here we get some basic attributes. shDesktop.GetAttributesOf(1, out m_pIDL, out uFlags); IsFolder = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FOLDER); HasSubFolder = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_HASSUBFOLDER); // Now we want to get extended attributes such as the icon index etc. ShellAPI.SHFILEINFO shInfo = new ShellAPI.SHFILEINFO(); ShellAPI.SHGFI vFlags = //ShellAPI.SHGFI.SHGFI_ICON | ShellAPI.SHGFI.SHGFI_SMALLICON | ShellAPI.SHGFI.SHGFI_SYSICONINDEX | ShellAPI.SHGFI.SHGFI_PIDL | ShellAPI.SHGFI.SHGFI_DISPLAYNAME; ShellAPI.SHGetFileInfo(m_pIDL, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), vFlags); DisplayName = shInfo.szDisplayName; IconIndex = shInfo.iIcon; Path = GetPath(); // Create the IShellFolder interface for this item. if (IsFolder) { uint hRes = shParent.m_shShellFolder.BindToObject(pIDL, IntPtr.Zero, ref ShellAPI.IID_IShellFolder, out m_shShellFolder); if (hRes != 0) { Marshal.ThrowExceptionForHR((int)hRes); } } //Icon icon = (Icon)Icon.FromHandle(shInfo.hIcon).Clone(); //icon.ToBitmap().Save(shInfo.szDisplayName + ".png"); //User32.DestroyIcon(shInfo.hIcon); }
/// <summary> /// 属性を初期化する。 /// </summary> private void InitAtr(InitMode mode, IntPtr pIDL, ShellAPI.IShellFolder parentSf) { // 基本的な属性を初期化する ShellAPI.SFGAOF uFlags = 0; switch (mode) { case InitMode.Desktop: { this.IsFolder = true; this.IsFileSystem = false; this.HasSubFolder = true; } break; case InitMode.Path: case InitMode.Child: { uFlags = ShellAPI.SFGAOF.SFGAO_FOLDER | ShellAPI.SFGAOF.SFGAO_FILESYSTEM | ShellAPI.SFGAOF.SFGAO_FILESYSANCESTOR; parentSf.GetAttributesOf(1, out pIDL, out uFlags); this.IsFolder = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FOLDER); this.IsFileSystem = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FILESYSTEM); if (this.IsFolder) { // GetAttributesOf で SFGAO_HASSUBFOLDER を調べるとかなり遅くなる、 // そもそも this.HasSubFolder はヒントとして使用するだけなのでフォルダの場合は問答無用で // this.HasSubFolder に true をセットする this.HasSubFolder = true; // このオブジェクト用の IShellFolder インターフェース取得 m_ShellFolder = ShellAPI.BindToIShellFolder(parentSf, pIDL); } } break; } // パス名取得 m_Path = ShellAPI.SHGetPathFromIDList(m_pIDL); // アイコンインデックス番号とかの属性取得 ShellAPI.SHFILEINFO shInfo = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfoW( m_pIDL, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), ShellAPI.SHGFI.SHGFI_SMALLICON | ShellAPI.SHGFI.SHGFI_SYSICONINDEX | ShellAPI.SHGFI.SHGFI_PIDL | ShellAPI.SHGFI.SHGFI_DISPLAYNAME | ShellAPI.SHGFI.SHGFI_TYPENAME ); m_DisplayName = shInfo.szDisplayName; m_TypeName = shInfo.szTypeName; m_iIconIndex = shInfo.iIcon; // 選択時のアイコンインデックス番号取得 ShellAPI.SHGetFileInfoW( m_pIDL, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), ShellAPI.SHGFI.SHGFI_PIDL | ShellAPI.SHGFI.SHGFI_SMALLICON | ShellAPI.SHGFI.SHGFI_SYSICONINDEX | ShellAPI.SHGFI.SHGFI_OPENICON ); m_iSelectedIconIndex = shInfo.iIcon; // いろいろ調べてアイテム種類(m_ItemType)を確定する if (this.IsFileSystem) { bool bValidated = false; m_FileName = ""; try { m_FileName = System.IO.Path.GetFileName(m_Path); if (this.IsFolder) { if (System.IO.Path.GetPathRoot(m_Path) == m_Path) { // パス名とルートパスが同じならドライブのはず m_ItemType = ShellItemType.Drive; bValidated = true; } else if (Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FILESYSANCESTOR)) { // ファイルシステムアイテムを含むことができるフォルダ=ファイルフォルダ(だと思う) m_ItemType = ShellItemType.Folder; bValidated = true; } } } catch { // システムのアイテムの場合まともなパス名ではなくて、例外が出ちゃうので // ここで例外キャッチ } if (!bValidated) { m_ItemType = ShellItemType.File; bValidated = true; } } else { if (this.IsFolder) { m_ItemType = ShellItemType.SpecialFolder; } else { m_ItemType = ShellItemType.SpecialItem; } } }
/// <summary> /// Constructor. Create a sub-item shell item object. /// </summary> /// <param name="shFolder">IShellFolder interface of the Desktop</param> /// <param name="pIDL">The fully qualified PIDL for this shell item</param> /// <param name="shellDesktop">The ShellItem object for desktop</param> public DataSourceShell(ShellAPI.IShellFolder shellDesktop, IntPtr pIDL, DataSourceShell shellParent, bool hasOnlyFolders, SpecialFolderType folderType) { _specialFolderType = folderType; // We need the Desktop shell item to exist first. if (haveRootShell == false) { throw new Exception("The root shell item must be created before creating a sub-item"); } // Create the FQ PIDL for this new item. ptrIDL = ShellAPI.ILCombine(shellParent.PIDL, pIDL); shellItemPath = GetPath(); // Get the properties of this item. ShellAPI.SFGAOF uFlags = ShellAPI.SFGAOF.SFGAO_FOLDER | //ShellAPI.SFGAOF.SFGAO_HASSUBFOLDER | ShellAPI.SFGAOF.SFGAO_BROWSABLE | ShellAPI.SFGAOF.SFGAO_STREAM | ShellAPI.SFGAOF.SFGAO_LINK | ShellAPI.SFGAOF.SFGAO_FILESYSTEM | ShellAPI.SFGAOF.SFGAO_HIDDEN | ShellAPI.SFGAOF.SFGAO_REMOVABLE ; // Here we get some basic attributes. uint result = shellParent.shellFolder.GetAttributesOf(1, ref pIDL, ref uFlags); isFolder = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FOLDER); hasSubFolder = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_HASSUBFOLDER); IsBrowsable = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_BROWSABLE); IsStream = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_STREAM); IsLink = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_LINK); isFileSystem = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FILESYSTEM); IsHidden = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_HIDDEN); IsRemovable = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_REMOVABLE); ShellAPI.IShellItem pshellitem; if (ShellAPI.SHCreateShellItem(IntPtr.Zero, null, PIDL, out pshellitem) == 0) { Int32 length = 0; if (ShellAPI.SHLoadLibraryFromItem(pshellitem, ref length) == 0) { _blibrary = true; } } IntPtr parseString = IntPtr.Zero; pshellitem.GetDisplayName(ShellAPI.SIGDN.SIGDN_DESKTOPABSOLUTEPARSING, out parseString); this.ParsingName = Marshal.PtrToStringAuto(parseString); LoadFileInfo(ptrIDL); // [1/18/2010 jozhang #92129] //when IsStream and isFolder is true,it means the file is .cab or .zip so isFolder should be changed to false; if (IsStream && isFolder) { isFolder = false; // In case of zip } try { // Create the IShellFolder interface for this item. if (IsFolder) { result = shellParent.shellFolder.BindToObject(pIDL, IntPtr.Zero, ref ShellAPI.IID_IShellFolder, out shellFolder); if (result != 0) { Marshal.ThrowExceptionForHR((int)result); } } } catch (Exception ex) { LogHelper.Debug("shellParent.shellFolder.BindToObject Failed", ex); } }