/// <remarks> /// This method will not update any registered components. /// It is for updating the coordinator's own state. /// </remarks> private Pidl BrowseToCore(Pidl pidl) { if (pidl != null && !pidl.IsFolder) { // if for some reason we're trying to browse to a file, use the file's location instead using (Pidl parent = pidl.GetParent()) { return(this.BrowseToCore(parent)); } } if (_browseHistory.Current != pidl) { Pidl clonePidl = null; if (pidl != null) { clonePidl = pidl.Clone(); } _browseHistory.Go(clonePidl); this.UpdateProperties(); this.OnCurrentPidlChanged(EventArgs.Empty); } return(_browseHistory.Current); }
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 }