/// <summary> /// Constructor. Creates the ShellItem object for the Desktop. /// </summary> public ShellItem() { // Obtain the root IShellFolder interface. int hRes = ShellAPI.SHGetDesktopFolder(ref m_shRootShell); if (hRes != 0) Marshal.ThrowExceptionForHR(hRes); // Now get the PIDL for the Desktop shell item. hRes = ShellAPI.SHGetSpecialFolderLocation(IntPtr.Zero, ShellAPI.CSIDL.CSIDL_DESKTOP, ref m_pIDL); if (hRes != 0) Marshal.ThrowExceptionForHR(hRes); // Now retrieve some attributes for the root shell item. ShellAPI.SHFILEINFO shInfo = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(m_pIDL, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), ShellAPI.SHGFI.SHGFI_DISPLAYNAME | ShellAPI.SHGFI.SHGFI_PIDL | ShellAPI.SHGFI.SHGFI_SMALLICON | ShellAPI.SHGFI.SHGFI_SYSICONINDEX ); // Set the arributes to object properties. DisplayName = shInfo.szDisplayName; IconIndex = shInfo.iIcon; IsFolder = true; HasSubFolder = true; Path = GetPath(); // Internal with no set{} mutator. m_shShellFolder = RootShellFolder; m_bHaveRootShell = true; }
public void Dispose() { // Release the IShellFolder interface of this shell item. if (m_shShellFolder != null) { if (m_shShellFolder == ShellItem.m_shRootShell) { // If you release m_shRootShell you have also to update m_shRootShell and m_bHaveRootShell m_shRootShell = null; m_bHaveRootShell = false; Marshal.ReleaseComObject(m_shShellFolder); } else { Marshal.ReleaseComObject(m_shShellFolder); } } // Free the PIDL too. if (!m_pIDL.Equals(IntPtr.Zero)) { Marshal.FreeCoTaskMem(m_pIDL); } GC.SuppressFinalize(this); }
/// <summary> /// コンストラクタ。指定された ShellItem の子として初期化する。 /// 初期化途中で例外が発生したら pIDL を所有してはならない。 /// </summary> /// <param name="pIDL">子アイテムのITEMIDL。</param> /// <param name="shParent">親シェルアイテムオブジェクト。</param> private ShellItem(IntPtr pIDL, ShellItem shParent) { // ITEMIDLを連結 m_pIDL = ShellAPI.ILCombine(shParent.PIDL, pIDL); // 属性などいろいろ初期化する InitAtr(InitMode.Child, pIDL, shParent.ShellFolder); // 親 IShellFolder と親からの相対IDLを取得 m_ParentShellFolder = shParent.ShellFolder; m_pRelativeIDL = pIDL; }
/// <summary> /// Checks the type of the special folder. /// </summary> /// <param name="parent">The parent.</param> /// <param name="parentPIDL">The parent PIDL.</param> /// <param name="pidl">The pidl.</param> /// <returns></returns> SpecialFolderType CheckSpecialFolderType(ShellAPI.IShellFolder parent, IntPtr parentPIDL, IntPtr pidl) { IntPtr pIDLCombined = ShellAPI.ILCombine(parentPIDL, pidl); for (int i = 0; i < listSpecialFolders.Count; i++) { if (shellRoot.CompareIDs(0, listSpecialFolders[i].PIDL, pIDLCombined) == 0) { return(listSpecialFolders[i].FolderType); } } return(SpecialFolderType.None); }
/// <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> /// <param name="path">フルパス名。</param> public ShellItem(string path) { // 指定されたパスを指し示すITEMIDLを取得する m_pIDL = ShellAPI.ILCreateFromPathW(path); if (m_pIDL == IntPtr.Zero) { throw new Exception(string.Format("{0} は有効なパスではありません。", path)); } IntPtr parentIdl = IntPtr.Zero; try { // 指定されたパスの親のIDLを取得 parentIdl = ShellAPI.ILClone(m_pIDL); ShellAPI.ILRemoveLastID(parentIdl); // 親からの相対IDLを検索 IntPtr relativeIdl = ShellAPI.ILFindLastID(m_pIDL); // 相対IDLを取得(メモリ解放漏れさせないために即座にメンバ変数へ格納) m_pRelativeIDL = ShellAPI.ILClone(relativeIdl); // 指定されたパスの親のIShellFolderを取得 m_ParentShellFolder = ShellAPI.BindToIShellFolder(DesktopShellItem.ShellFolder, parentIdl); // 属性などいろいろ初期化する InitAtr(InitMode.Path, m_pRelativeIDL, m_ParentShellFolder); } finally { if (parentIdl != IntPtr.Zero) { Marshal.FreeCoTaskMem(parentIdl); } } }
/// <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); } }
public DirectoryHelper(ShellAPI.IShellFolder shellFolder, IntPtr pidl) { ShellFolder = shellFolder; _pIDL = pidl; }