www.pudn.com > FileSecurity.rar > ShellItem.cs


using System; 
using System.Text; 
using System.Collections; 
using System.Runtime.InteropServices; 
 
namespace FileSecurity 
{ 
    class ShellItem 
    { 
        #region Private Member Variables 
 
        private static Boolean m_bHaveRootShell = false; 
 
        #endregion 
 
        #region Constructor 
 
        public ShellItem() 
        { 
            if (m_bHaveRootShell) 
                throw new Exception("The Desktop shell item already exists so cannot be created again."); 
 
            int hRes = ShellAPI.SHGetDesktopFolder(ref m_shRootShell); 
            if (hRes != 0) 
                Marshal.ThrowExceptionForHR(hRes); 
 
            hRes = ShellAPI.SHGetSpecialFolderLocation(IntPtr.Zero, ShellAPI.CSIDL.CSIDL_DESKTOP, ref m_pIDL); 
            if (hRes != 0) 
                Marshal.ThrowExceptionForHR(hRes); 
 
            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 
            ); 
 
            DisplayName  = shInfo.szDisplayName; 
            IconIndex    = shInfo.iIcon; 
            IsFolder     = true; 
            HasSubFolder = true; 
            Path         = GetPath(); 
 
            m_shShellFolder  = RootShellFolder; 
            m_bHaveRootShell = true; 
        } 
 
        public ShellItem(ShellAPI.IShellFolder shDesktop, IntPtr pIDL, ShellItem shParent) 
        { 
            if (m_bHaveRootShell == false) 
                throw new Exception("The root shell item must be created before creating a sub-item"); 
 
            m_pIDL = ShellAPI.ILCombine(shParent.PIDL, pIDL); 
 
            ShellAPI.SFGAOF uFlags = ShellAPI.SFGAOF.SFGAO_FOLDER | ShellAPI.SFGAOF.SFGAO_HASSUBFOLDER; 
 
            shDesktop.GetAttributesOf(1, out m_pIDL, out uFlags); 
            IsFolder = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FOLDER); 
            HasSubFolder = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_HASSUBFOLDER); 
 
            ShellAPI.SHFILEINFO shInfo = new ShellAPI.SHFILEINFO(); 
            ShellAPI.SHGFI vFlags = 
                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(); 
 
            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); 
            } 
        } 
 
        #endregion 
 
        #region Destructor 
 
        ~ShellItem() 
        { 
            if (m_shShellFolder != null) 
                Marshal.ReleaseComObject(m_shShellFolder); 
 
            if (!m_pIDL.Equals(IntPtr.Zero)) 
                Marshal.FreeCoTaskMem(m_pIDL); 
 
            GC.SuppressFinalize(this); 
        } 
 
        #endregion 
 
        #region Public Methods 
 
        public string GetPath() 
        { 
            StringBuilder strBuffer = new StringBuilder(256); 
            ShellAPI.SHGetPathFromIDList( 
                m_pIDL,  
                strBuffer 
            ); 
            return strBuffer.ToString(); 
        } 
 
        public ArrayList GetSubFolders() 
        { 
            if (IsFolder == false) 
                throw new Exception("Unable to retrieve sub-folders for a non-folder."); 
 
            ArrayList arrChildren = new ArrayList(); 
            try 
            { 
                ShellAPI.IEnumIDList pEnum = null; 
                uint hRes = ShellFolder.EnumObjects(IntPtr.Zero, ShellAPI.SHCONTF.SHCONTF_FOLDERS, out pEnum); 
                if (hRes != 0) 
                    Marshal.ThrowExceptionForHR((int)hRes); 
                 
                IntPtr pIDL = IntPtr.Zero; 
                Int32 iGot = 0; 
 
                pEnum.Next(1, out pIDL, out iGot); 
 
                while (!pIDL.Equals(IntPtr.Zero) && iGot == 1) 
                { 
                    arrChildren.Add(new ShellItem(m_shRootShell, pIDL, this)); 
 
                    Marshal.FreeCoTaskMem(pIDL); 
                    pIDL = IntPtr.Zero; 
                    iGot = 0; 
 
                    pEnum.Next(1, out pIDL, out iGot); 
                } 
 
                if (pEnum != null) 
                    Marshal.ReleaseComObject(pEnum); 
            } 
            catch (Exception ex) 
            { 
                System.Windows.Forms.MessageBox.Show(ex.Message, "Error:", 
                    System.Windows.Forms.MessageBoxButtons.OK, 
                    System.Windows.Forms.MessageBoxIcon.Error 
                ); 
            } 
 
            return arrChildren; 
        } 
 
        #endregion 
 
        #region Properties 
 
        public string DisplayName 
        { 
            get { return m_strDisplayName; } 
            set { m_strDisplayName = value; } 
        } 
        string m_strDisplayName = ""; 
 
        public Int32 IconIndex 
        { 
            get { return m_iIconIndex; } 
            set { m_iIconIndex = value; } 
        } 
        Int32 m_iIconIndex = -1; 
 
        public ShellAPI.IShellFolder RootShellFolder 
        { 
            get { return m_shRootShell; } 
        } 
        static ShellAPI.IShellFolder m_shRootShell = null; 
 
        public ShellAPI.IShellFolder ShellFolder 
        { 
            get { return m_shShellFolder; } 
        } 
        ShellAPI.IShellFolder m_shShellFolder = null; 
 
        public IntPtr PIDL 
        { 
            get { return m_pIDL; } 
        } 
        IntPtr m_pIDL = IntPtr.Zero; 
 
        public bool IsFolder 
        { 
            get { return m_bIsFolder; } 
            set { m_bIsFolder = value; } 
        } 
        bool m_bIsFolder = false; 
 
        public bool HasSubFolder 
        { 
            get { return m_bHasSubFolder; } 
            set { m_bHasSubFolder = value; } 
        } 
        bool m_bHasSubFolder = false; 
 
        public string Path 
        { 
            get { return m_strPath;  } 
            set { m_strPath = value; } 
        } 
        string m_strPath = ""; 
 
        #endregion 
    } 
}