Пример #1
0
		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
		}
Пример #2
0
		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);
		}
Пример #3
0
			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)));
			}
Пример #4
0
		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
		}
Пример #5
0
		public static extern IntPtr SHGetFileInfo(IntPtr pIDL, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);
Пример #6
0
		public static extern IntPtr SHGetFileInfo([MarshalAs(UnmanagedType.LPTStr)] string pszPath, uint dwFileAttribs, out SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);