public ShellItem() { _rootItem = this; try { // create a PIDL for the Desktop shell item. _pidl = new Pidl(Environment.SpecialFolder.Desktop); var shInfo = new Native.SHFILEINFO(); Native.Shell32.SHGetFileInfo((IntPtr) _pidl, 0, out shInfo, (uint) Marshal.SizeOf(shInfo), SHGFI.SHGFI_PIDL | SHGFI.SHGFI_DISPLAYNAME | SHGFI.SHGFI_SYSICONINDEX); // get the root IShellFolder interface int hResult = Native.Shell32.SHGetDesktopFolder(ref _shellFolder); if (hResult != 0) Marshal.ThrowExceptionForHR(hResult); _displayName = shInfo.szDisplayName; _typeName = string.Empty; _iconIndex = shInfo.iIcon; _isFolder = true; _isVirtual = true; _hasSubFolders = true; } catch (Exception ex) { // if an exception happens during construction, we must release the PIDL now (remember, it's a pointer!) if (_pidl != null) _pidl.Dispose(); throw new Exception("Creation of the root namespace shell item failed.", ex); } #if DEBUG _instanceCount++; #endif }
private SystemImageList(bool useSmallIcons) { //JY: We use static instances here without IDisposable here because the system image list is allocated // to us by shell32, and we only get one per process for a given icon size. Even doing an ImageList_Destroy // in a destructor can cause funny business. const int FILE_ATTRIBUTE_NORMAL = 0x80; // retrieve the info for a fake file so we can get the image list handle. Native.SHFILEINFO shInfo = new Native.SHFILEINFO(); Native.SHGFI uFlags = Native.SHGFI.SHGFI_USEFILEATTRIBUTES | Native.SHGFI.SHGFI_SYSICONINDEX; if (useSmallIcons) uFlags |= Native.SHGFI.SHGFI_SMALLICON; else uFlags |= Native.SHGFI.SHGFI_LARGEICON; _handle = Native.Shell32.SHGetFileInfo(".txt", FILE_ATTRIBUTE_NORMAL, out shInfo, (uint) Marshal.SizeOf(shInfo), uFlags); }
private SystemImageList(bool useSmallIcons) { //JY: We use static instances here without IDisposable here because the system image list is allocated // to us by shell32, and we only get one per process for a given icon size. Even doing an ImageList_Destroy // in a destructor can cause funny business. const int FILE_ATTRIBUTE_NORMAL = 0x80; // retrieve the info for a fake file so we can get the image list handle. Native.SHFILEINFO shInfo = new Native.SHFILEINFO(); Native.SHGFI uFlags = Native.SHGFI.SHGFI_USEFILEATTRIBUTES | Native.SHGFI.SHGFI_SYSICONINDEX; if (useSmallIcons) { uFlags |= Native.SHGFI.SHGFI_SMALLICON; } else { uFlags |= Native.SHGFI.SHGFI_LARGEICON; } _handle = Native.Shell32.SHGetFileInfo(".txt", FILE_ATTRIBUTE_NORMAL, out shInfo, (uint)Marshal.SizeOf(shInfo), uFlags); }
public ShellItem() { _rootItem = this; try { // create a PIDL for the Desktop shell item. _pidl = new Pidl(Environment.SpecialFolder.Desktop); var shInfo = new Native.SHFILEINFO(); Native.Shell32.SHGetFileInfo((IntPtr)_pidl, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), SHGFI.SHGFI_PIDL | SHGFI.SHGFI_DISPLAYNAME | SHGFI.SHGFI_SYSICONINDEX); // get the root IShellFolder interface int hResult = Native.Shell32.SHGetDesktopFolder(ref _shellFolder); if (hResult != 0) { Marshal.ThrowExceptionForHR(hResult); } _displayName = shInfo.szDisplayName; _typeName = string.Empty; _iconIndex = shInfo.iIcon; _isFolder = true; _isVirtual = true; _hasSubFolders = true; } catch (Exception ex) { // if an exception happens during construction, we must release the PIDL now (remember, it's a pointer!) if (_pidl != null) { _pidl.Dispose(); } throw new Exception("Creation of the root namespace shell item failed.", ex); } #if DEBUG _instanceCount++; #endif }
public FolderListViewItem(Pidl absolutePidl, Pidl myDocumentsReferencePidl, FileSizeFormat fileSizeFormat) { _pidl = absolutePidl; _fullPath = absolutePidl.Path; // request shell item info now - it's faster than binding to ShellItem directly, and we need it for sorting purposes anyway var uFlags = SHGFI.SHGFI_PIDL | SHGFI.SHGFI_TYPENAME | SHGFI.SHGFI_DISPLAYNAME | SHGFI.SHGFI_SYSICONINDEX; // bug #9975: asking for SHGFI_ATTRIBUTES can be a very slow operation, so we don't want to ask for them unless we really need them. // if we're dealing with a regular file or directory, then getting the attributes gives us no additional information, so we can avoid it var isFile = !string.IsNullOrEmpty(_fullPath) && File.Exists(_fullPath); var isDirectory = !string.IsNullOrEmpty(_fullPath) && Directory.Exists(_fullPath); if (!isFile && !isDirectory) { uFlags = uFlags | SHGFI.SHGFI_ATTRIBUTES; } var shInfo = new SHFILEINFO(); Shell32.SHGetFileInfo((IntPtr) _pidl, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), uFlags); // check if item is purely virtual or is a physical file system object var isPureVirtual = !isFile && !isDirectory && ((SFGAO)shInfo.dwAttributes & SFGAO.SFGAO_FILESYSTEM) == 0; // check if item is actually a folder or potentially has subfolders; exclude real files that provide subfolders via shell namespace extensions (e.g. ZIP files in WinXP) var isFolder = isDirectory || (((SFGAO) shInfo.dwAttributes & (SFGAO.SFGAO_FOLDER | SFGAO.SFGAO_HASSUBFOLDER)) != 0 && !isFile); byte itemClass; if (_pidl == myDocumentsReferencePidl) itemClass = 0; else if (isPureVirtual && isFolder) itemClass = 64; else if (isFolder) itemClass = (byte) (128 + GetRootVolumeIndex(_fullPath)); else itemClass = byte.MaxValue; this._iconIndex = shInfo.iIcon; this._lastModifiedValid = false; this.DisplayName = shInfo.szDisplayName; this.TypeName = shInfo.szTypeName; this.ItemClass = itemClass; this.LastModified = DateTime.MinValue; this.IsFolder = isFolder; this.FileSize = -1; if (File.Exists(_fullPath)) { FileInfo fileInfo = new FileInfo(this._fullPath); this._lastModifiedValid = true; this.LastModified = fileInfo.LastWriteTime; this.FileSize = fileInfo.Length; } else if (Directory.Exists(_fullPath)) { this._lastModifiedValid = true; this.LastModified = Directory.GetLastWriteTime(_fullPath); } this.Text = this.DisplayName; this.ImageIndex = this._iconIndex; this.SubItems.Add(CreateSubItem(this, FormatFileSize(this.FileSize, fileSizeFormat))); this.SubItems.Add(CreateSubItem(this, this.TypeName)); this.SubItems.Add(CreateSubItem(this, FormatLastModified(this.LastModified, this._lastModifiedValid))); }
public ShellItem(Pidl pidl, ShellItem parentShellItem, bool relativePidl) { int hResult; _rootItem = parentShellItem._rootItem; try { IntPtr tempPidl; if (relativePidl) { _pidl = new Pidl(parentShellItem.Pidl, pidl); tempPidl = (IntPtr) pidl; // use the relative one from parameters } else { _pidl = pidl.Clone(); tempPidl = (IntPtr) _pidl; // use the absolute one that we constructed just now } const Native.SHGFI flags = Native.SHGFI.SHGFI_PIDL // indicates that we're specifying the item by PIDL | Native.SHGFI.SHGFI_DISPLAYNAME // indicates that we want the item's display name | Native.SHGFI.SHGFI_SYSICONINDEX // indicates that we want the item's icon's index in the system image list | Native.SHGFI.SHGFI_ATTRIBUTES // indicates that we want the item's attributes | Native.SHGFI.SHGFI_TYPENAME; // indicates that we want the item's type name Native.SHFILEINFO shInfo = new Native.SHFILEINFO(); Native.Shell32.SHGetFileInfo((IntPtr) _pidl, 0, out shInfo, (uint) Marshal.SizeOf(shInfo), flags); // read item attributes Native.SFGAO attributeFlags = (Native.SFGAO) shInfo.dwAttributes; // create the item's IShellFolder interface if ((attributeFlags & Native.SFGAO.SFGAO_FOLDER) != 0) { Guid iidIShellFolder = new Guid(IID.IID_IShellFolder); if (_pidl == _rootItem._pidl) { // if the requested PIDL is the root namespace (the desktop) we can't use the the BindToObject method, so get it directly hResult = Native.Shell32.SHGetDesktopFolder(ref _shellFolder); } else { if (relativePidl) hResult = (int) parentShellItem._shellFolder.BindToObject(tempPidl, IntPtr.Zero, ref iidIShellFolder, out _shellFolder); else hResult = (int) _rootItem._shellFolder.BindToObject(tempPidl, IntPtr.Zero, ref iidIShellFolder, out _shellFolder); } if (hResult != 0) { // some objects are marked as folders, but really aren't and thus cannot be bound to an IShellFolder // log these events for future study, but it's not exactly something to be concerned about in isolated cases. // Marshal.ThrowExceptionForHR(hResult); if ((attributeFlags & Native.SFGAO.SFGAO_HASSUBFOLDER) == 0) attributeFlags = attributeFlags & ~Native.SFGAO.SFGAO_FOLDER; } } _displayName = shInfo.szDisplayName; _typeName = shInfo.szTypeName; _iconIndex = shInfo.iIcon; _isFolder = (attributeFlags & Native.SFGAO.SFGAO_FOLDER) != 0; _isVirtual = (attributeFlags & Native.SFGAO.SFGAO_FILESYSTEM) == 0; _hasSubFolders = (attributeFlags & Native.SFGAO.SFGAO_HASSUBFOLDER) != 0; } catch (Exception ex) { // if an exception happens during construction, we must release the PIDL now (remember, it's a pointer!) if (_pidl != null) _pidl.Dispose(); throw new Exception("Creation of the specified shell item failed.", ex); } #if DEBUG _instanceCount++; #endif }
public ShellItem(Pidl pidl, ShellItem parentShellItem, bool relativePidl) { int hResult; _rootItem = parentShellItem._rootItem; try { IntPtr tempPidl; if (relativePidl) { _pidl = new Pidl(parentShellItem.Pidl, pidl); tempPidl = (IntPtr)pidl; // use the relative one from parameters } else { _pidl = pidl.Clone(); tempPidl = (IntPtr)_pidl; // use the absolute one that we constructed just now } const Native.SHGFI flags = Native.SHGFI.SHGFI_PIDL // indicates that we're specifying the item by PIDL | Native.SHGFI.SHGFI_DISPLAYNAME // indicates that we want the item's display name | Native.SHGFI.SHGFI_SYSICONINDEX // indicates that we want the item's icon's index in the system image list | Native.SHGFI.SHGFI_ATTRIBUTES // indicates that we want the item's attributes | Native.SHGFI.SHGFI_TYPENAME; // indicates that we want the item's type name Native.SHFILEINFO shInfo = new Native.SHFILEINFO(); Native.Shell32.SHGetFileInfo((IntPtr)_pidl, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), flags); // read item attributes Native.SFGAO attributeFlags = (Native.SFGAO)shInfo.dwAttributes; // create the item's IShellFolder interface if ((attributeFlags & Native.SFGAO.SFGAO_FOLDER) != 0) { Guid iidIShellFolder = new Guid(IID.IID_IShellFolder); if (_pidl == _rootItem._pidl) { // if the requested PIDL is the root namespace (the desktop) we can't use the the BindToObject method, so get it directly hResult = Native.Shell32.SHGetDesktopFolder(ref _shellFolder); } else { if (relativePidl) { hResult = (int)parentShellItem._shellFolder.BindToObject(tempPidl, IntPtr.Zero, ref iidIShellFolder, out _shellFolder); } else { hResult = (int)_rootItem._shellFolder.BindToObject(tempPidl, IntPtr.Zero, ref iidIShellFolder, out _shellFolder); } } if (hResult != 0) { // some objects are marked as folders, but really aren't and thus cannot be bound to an IShellFolder // log these events for future study, but it's not exactly something to be concerned about in isolated cases. // Marshal.ThrowExceptionForHR(hResult); if ((attributeFlags & Native.SFGAO.SFGAO_HASSUBFOLDER) == 0) { attributeFlags = attributeFlags & ~Native.SFGAO.SFGAO_FOLDER; } } } _displayName = shInfo.szDisplayName; _typeName = shInfo.szTypeName; _iconIndex = shInfo.iIcon; _isFolder = (attributeFlags & Native.SFGAO.SFGAO_FOLDER) != 0; _isVirtual = (attributeFlags & Native.SFGAO.SFGAO_FILESYSTEM) == 0; _hasSubFolders = (attributeFlags & Native.SFGAO.SFGAO_HASSUBFOLDER) != 0; } catch (UnauthorizedAccessException ex) { // if an exception happens during construction, we must release the PIDL now (remember, it's a pointer!) var path = string.Empty; if (_pidl != null) { path = _pidl.Path; _pidl.Dispose(); } throw new PathAccessException(path, ex); } catch (Exception ex) { // if an exception happens during construction, we must release the PIDL now (remember, it's a pointer!) if (_pidl != null) { _pidl.Dispose(); } throw new Exception("Creation of the specified shell item failed.", ex); } #if DEBUG _instanceCount++; #endif }
public static extern IntPtr SHGetFileInfo(IntPtr pIDL, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);
public static extern IntPtr SHGetFileInfo([MarshalAs(UnmanagedType.LPTStr)] string pszPath, uint dwFileAttribs, out SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);