Example #1
0
        private static string ValidateNotExistingPidl(ShellItemIdList pidl)
        {
            // this must be compatible with what we sent in TryParseItem method
            var stringPidl = KeyShellItemId.From(pidl?.Last?.Data, false) as StringKeyShellItemId;

            return(stringPidl?.Value);
        }
Example #2
0
        public RootFolder(PhysicalOverviewShellFolderServer server, ShellItemIdList idList)
            : base(idList)
        {
            if (server == null)
            {
                throw new ArgumentNullException(nameof(server));
            }

            Hello = new HelloWorldItem(this);

            // get a path like C:\Users\<user>\AppData\Local\ShellBoost.Samples.PhysicalOverview\Root
            RootPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), GetType().Namespace), "Root");

            // ensure it exists
            var di = new DirectoryInfo(RootPath);

            if (!di.Exists)
            {
                di.Create();
            }

            RootPhysical = new PhysicalFolder(this, di);
            Server       = server;

            // we want to know when something changes in the real folder so we can update ours
            // note we don't use .NET's FileSystemWatcher but a Shell-oriented ShellBoost-provider tool instead base on native Shell's APIs.
            ChangeNotifier         = new ChangeNotifier(ShellUtilities.GetIdList(RootPath), true);
            ChangeNotifier.Notify += OnChangeNotifierNotify;
        }
Example #3
0
        public override bool TryParseItem(ShellBindContext context, string displayName, out int eatenCharacters, out SFGAO attributes, out ShellItemIdList relativeIdl)
        {
            eatenCharacters = 0;
            attributes      = SFGAO.SFGAO_NONE;

            // Windows Shell is calling us because it found no item
            // This may be called in the context of a common dialog box

            // is it for creation? item does not necessarily exist
            if (context.Mode.HasFlag(STGM.STGM_CREATE))
            {
                // the default SFGAO for an item (+ SFGAO_FILESYSTEM)
                // note for creation mode we only send items back, not folders.
                attributes = DefaultItemAttributes | SFGAO.SFGAO_FILESYSTEM;

                // come up with some PIDL that we'll be able to recognize later (using ValidateNotExistingPidl)
                // you can use your usual "real" ShellItemIdList but in this sample, we use fake ones because we don't want to create guids that don't exist in the web (api).
                relativeIdl = new ShellItemIdList();
                relativeIdl.Add(new StringKeyShellItemId(displayName));
                return(true);
            }

            // here, item must exist
            // displayName can be a name or a path (relative) and can ends with \ so we normalize it
            var path = IOUtilities.StripTerminatingPathSeparators(displayName);
            var item = ParseItem(path, out relativeIdl); // this will call into our GetItem implementation recursively

            if (item != null)
            {
                attributes = item.Attributes;
                return(true);
            }

            return(false); // don't go to base, we know better
        }
Example #4
0
 protected override RootShellFolder GetRootFolder(ShellItemIdList idl)
 {
     if (_drive == null)
     {
         _drive = new RootWebShellFolder(this, idl);
     }
     return(_drive);
 }
Example #5
0
 protected override ShellFolder GetFolderAsRoot(ShellItemIdList idl)
 {
     if (_root == null)
     {
         _root = new WebShellFolder(idl);
     }
     return(_root);
 }
Example #6
0
 protected override RootShellFolder GetRootFolder(ShellItemIdList idl)
 {
     if (_root == null)
     {
         _root = new RootFolder(this, idl);
     }
     return(_root);
 }
 /// <summary>
 /// Gets the root folder.
 /// </summary>
 /// <param name="idl">The root folder PIDL.</param>
 /// <returns>An instance of the RootShellFolder type.</returns>
 protected override RootShellFolder GetRootFolder(ShellItemIdList idl)
 {
     if (RootFolder == null)
     {
         RootFolder = new OnDemandRootFolder(this, idl, Info);
     }
     return(RootFolder);
 }
Example #8
0
        public RootFolder(OverviewShellFolderServer server, ShellItemIdList idList)
            : base(idList)
        {
            if (server == null)
            {
                throw new ArgumentNullException(nameof(server));
            }

            Server = server;
        }
Example #9
0
        public RootFolder(LocalShellFolderServer server, ShellItemIdList idList)
            : base(idList)
        {
            if (server == null)
            {
                throw new ArgumentNullException(nameof(server));
            }

            Server      = server;
            _dropTarget = new DropTargetShellFolder(this);
        }
Example #10
0
        public override bool TryGetDisplayName(ShellItemIdList relativeIdl, out string displayName)
        {
            var name = ValidateNotExistingPidl(relativeIdl);

            if (name == null) // ? this is not ours
            {
                return(base.TryGetDisplayName(relativeIdl, out displayName));
            }

            displayName = name;
            return(true);
        }
        public ArchiveRootShellFolder(SevenZipShellFolderServer server, ShellItemIdList idList)
            : base(idList)
        {
            if (server == null)
            {
                throw new ArgumentNullException(nameof(server));
            }

            Server      = server;
            Archive     = new ArchiveRootFolderInfo(idList.GetFileSystemPath());
            DisplayName = Path.GetFileName(Archive.FilePath);
        }
Example #12
0
        // use root folder constructor
        public RootFolder(string rootPath, ShellItemIdList idList)
            : base(idList)
        {
            if (rootPath == null)
            {
                throw new ArgumentNullException(nameof(rootPath));
            }

            // this sample works just because of this line
            // all the rest will be automatically built because we're using file system
            FileSystemPath = rootPath;
        }
Example #13
0
        public DeviceManagerFolder(ShellItemIdList idList)
            : base(idList)
        {
            // remove default columns we don't need here
            RemoveColumn(Props.System.ItemType);
            RemoveColumn(Props.System.Size);
            RemoveColumn(Props.System.DateModified);
            RemoveColumn(Props.System.PerceivedType);
            RemoveColumn(Props.System.Kind);

            // add this one, already defined by Windows
            AddColumn(Props.System.Devices.ClassGuid, SHCOLSTATE.SHCOLSTATE_ONBYDEFAULT);
        }
Example #14
0
        public override bool TryGetAttributes(ShellItemIdList relativeIdl, out SFGAO attributes)
        {
            var name = ValidateNotExistingPidl(relativeIdl);

            if (name == null) // ? this is not ours
            {
                return(base.TryGetAttributes(relativeIdl, out attributes));
            }

            // the default SFGAO for an item (+ SFGAO_FILESYSTEM)
            attributes = DefaultItemAttributes | SFGAO.SFGAO_FILESYSTEM;
            return(true);
        }
Example #15
0
        public RootFolder(RegistryShellFolderServer server, ShellItemIdList idList)
            : base(idList)
        {
            if (server == null)
            {
                throw new ArgumentNullException(nameof(server));
            }

            Server = server;
            RemoveColumn(Props.System.ItemType);
            RemoveColumn(Props.System.Size);
            RemoveColumn(Props.System.DateModified);
            RemoveColumn(Props.System.PerceivedType);
            RemoveColumn(Props.System.Kind);
        }
Example #16
0
        // root folder
        public WebShellFolder(ShellItemIdList idList)
            : base(idList)
        {
            CanLink      = true;
            IsDropTarget = true;

            ApiItem             = new WebItem(); // root's id is guid empty
            ApiItem.Attributes |= FileAttributes.Directory;
            ApiItem.IsRoot      = true;

            Attributes |= SFGAO.SFGAO_STORAGE;

            // root is a "physical" shell item
            FileSystemPath = WebApi.LocalDirectory.FullName;
            DisplayName    = "Samples.CloudFolder";
            DefineExtraColumns();
        }
        // ShellBoost will call that method each time an archive file is open using the Shell
        protected override RootShellFolder GetRootFolder(ShellItemIdList idList)
        {
            if (idList == null)
            {
                throw new ArgumentNullException(nameof(idList));
            }

            if (!_cache.TryGetValue(idList, out var folder))
            {
                // this check to ensure we're not being called for anything else than what we expect (like a folder, etc.)
                var path = idList.GetFileSystemPath();
                if (IOUtilities.FileExists(path))
                {
                    folder = new ArchiveRootShellFolder(this, idList);
                }
                _cache[idList] = folder; // we also store null
            }
            return(folder);
        }
Example #18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OnDemandRootFolder"/> class.
        /// </summary>
        /// <param name="server">The folder server.</param>
        /// <param name="idList">The root folder PIDL.</param>
        /// <param name="info">The root folder directory.</param>
        /// <exception cref="ArgumentNullException">
        /// server is null
        /// or
        /// info is null.
        /// </exception>
        public OnDemandRootFolder(OnDemandShellFolderServer server, ShellItemIdList idList, DirectoryInfo info)
            : base(idList, info)
        {
            if (server == null)
            {
                throw new ArgumentNullException(nameof(server));
            }

            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            Server = server;

            // since this is a FileSystem oriented NSE, we let base properties pass through
            ReadPropertiesFromShell = true;

            /// We just add the sync status column.
            AddColumn(Props.System.StorageProviderUIStatus, SHCOLSTATE.SHCOLSTATE_ONBYDEFAULT);
        }
        protected override ShellFolder GetFolderAsRoot(ShellItemIdList idList)
        {
            if (_root == null)
            {
                lock (_lock)
                {
                    // now, we're creating the root folder, so we add all previous actions to it
                    _root = new DeviceManagerFolder(idList);

                    var deviceInterfaces = _added.ToArray();
                    _added.Clear();

                    var updates = _updated.ToArray();
                    _updated.Clear();

                    var removed = _removed.ToArray();
                    _removed.Clear();

                    Task.Run(() =>
                    {
                        foreach (var deviceInterface in deviceInterfaces)
                        {
                            _ = _root.AddDeviceInterface(deviceInterface);
                        }

                        foreach (var update in updates)
                        {
                            _root.UpdateDeviceInterface(update);
                        }

                        foreach (var remove in removed)
                        {
                            _root.RemoveDeviceInterface(remove);
                        }
                    });
                }
            }
            return(_root);
        }
Example #20
0
 internal new ShellItem GetFromCache(ShellItemIdList idList) => base.GetFromCache(idList);
        private void OnChangeNotifierNotify(object sender, ChangeNotifyEventArgs e)
        {
            // get our equivalent item
            if (e.FileSystemPath1 != null)
            {
                // is it really about us?
                if (e.FileSystemPath1.StartsWith(RootPath, StringComparison.OrdinalIgnoreCase))
                {
                    // get relative path and normalize a bit
                    var relPath1 = IOUtilities.PathRemoveStartSlash(e.FileSystemPath1.Substring(RootPath.Length));

                    // build a PIDL corresponding to our namespace from a file system path (not in our namespace)
                    // and get/update the corresponding ShellItem from the cache, if it exists.
                    ShellItem       item;
                    ShellItemIdList idl;
                    switch (e.Event)
                    {
                    case SHCNE.SHCNE_DELETE:
                    case SHCNE.SHCNE_RMDIR:
                        idl  = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath1, e.Event == SHCNE.SHCNE_RMDIR ? FileAttributes.Directory : FileAttributes.Normal);
                        item = Server.GetFromCache(idl);
                        if (item != null)
                        {
                            item.NotifyDelete();
                            Server.RemoveFromCache(item.IdList);
                        }
                        break;

                    case SHCNE.SHCNE_RENAMEFOLDER:
                    case SHCNE.SHCNE_RENAMEITEM:
                        idl  = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath1, e.Event == SHCNE.SHCNE_RENAMEFOLDER ? FileAttributes.Directory : FileAttributes.Normal);
                        item = Server.GetFromCache(idl);
                        if (item != null)
                        {
                            Server.RemoveFromCache(item.IdList);
                        }

                        // 1 is previous, 2 is new
                        var relPath2 = IOUtilities.PathRemoveStartSlash(e.FileSystemPath2.Substring(RootPath.Length));
                        var idl2     = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath2, e.Event == SHCNE.SHCNE_RENAMEFOLDER ? FileAttributes.Directory : FileAttributes.Normal);
                        ShellUtilities.ChangeNotify(e.Event, 0, idl, idl2);
                        break;

                    case SHCNE.SHCNE_UPDATEITEM:
                    case SHCNE.SHCNE_UPDATEDIR:
                        idl  = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath1, e.Event == SHCNE.SHCNE_UPDATEDIR ? FileAttributes.Directory : FileAttributes.Normal);
                        item = Server.GetFromCache(idl);
                        if (item != null)
                        {
                            item.NotifyUpdate();
                        }
                        break;

                    case SHCNE.SHCNE_CREATE:
                    case SHCNE.SHCNE_MKDIR:
                        idl  = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath1, e.Event == SHCNE.SHCNE_MKDIR ? FileAttributes.Directory : FileAttributes.Normal);
                        item = Server.GetFromCache(idl);
                        if (item != null)     // item should in general be null (creation)
                        {
                            item.NotifyCreate();
                        }
                        else
                        {
                            ShellUtilities.ChangeNotify(e.Event, 0, idl);
                        }
                        break;
                    }
                }
            }
        }
 // constructor reserved for root
 public SimpleFolder(ShellItemIdList idList)
     : base(idList)
 {
     // Level = 0
 }
Example #23
0
 public RootWebShellFolder(WebShellFolderServer server, ShellItemIdList idList)
     : base(idList)
 {
     Server = server ?? throw new ArgumentNullException(nameof(server));
 }
 protected override RootShellFolder GetRootFolder(ShellItemIdList idl) => new RootFolder(this, idl);
Example #25
0
 internal new ShellItem RemoveFromCache(ShellItemIdList idList) => base.RemoveFromCache(idList);