Exemple #1
0
        // PSF sets the current directory and location to the script directory.
        // This is often useful and consistent with invoking from panels.
        // NOTE: ISE [F5] does not.
        public static void InvokeScriptBeingEdited(IEditor editor)
        {
            // editor
            if (editor == null)
            {
                editor = A.Psf.Editor();
            }

            // commit
            editor.Save();

            // sync the directory and location to the script directory
            // maybe it is questionable but it is very handy too often
            string dir0, dir1;

            // save/set the directory, allow failures (e.g. a long path)
            // note: GetDirectoryName fails on a long path, too
            try
            {
                dir1 = Path.GetDirectoryName(editor.FileName);
                dir0 = Environment.CurrentDirectory;
                Environment.CurrentDirectory = dir1;
            }
            catch (PathTooLongException)
            {
                // PowerShell is not able to invoke this script anyway, almost for sure
                Far.Api.Message("The script path is too long.\rInvoking is not supported.");
                return;
            }

            try
            {
                Far.Api.UI.WindowTitle = "Running...";

                // push/set the location; let's ignore issues
                A.Psf.Engine.SessionState.Path.PushCurrentLocation(null);
                A.Psf.Engine.SessionState.Path.SetLocation(Kit.EscapeWildcard(dir1));

                // invoke the script
                A.Psf.Act("& '" + editor.FileName.Replace("'", "''") + "'", null, false);
                Far.Api.UI.WindowTitle = "Done " + DateTime.Now;
            }
            catch
            {
                Far.Api.UI.WindowTitle = "Failed";
                throw;
            }
            finally
            {
                // restore the directory first
                Environment.CurrentDirectory = dir0;

                // then pop the location, it may fail perhaps
                A.Psf.Engine.SessionState.Path.PopLocation(null);
            }
        }
Exemple #2
0
        private void DoExplored(ItemExplorer explorer)
        {
            var info1 = explorer == null ? null : explorer.Info();
            var info2 = Explorer.Info();

            // fixed drive?
            if (Drive.Length > 0 && !Kit.Equals(Drive, info2.DriveName))
            {
                return;
            }

            // customise if not yet
            if (Drive.Length == 0 && (explorer == null || info1.Provider.ImplementingType != info2.Provider.ImplementingType))
            {
                if (string.IsNullOrEmpty(Drive))
                {
                    Columns = null;
                    ExcludeMemberPattern = null;

                    System.Collections.IDictionary options = A.Psf.Providers[info2.Provider.Name] as System.Collections.IDictionary;
                    if (options != null)
                    {
                        try
                        {
                            Converter.SetProperties(this, options, true);
                        }
                        catch (ArgumentException ex)
                        {
                            throw new InvalidDataException("Invalid settings for '" + info2.Provider.Name + "' provider: " + ex.Message);
                        }
                    }
                }
            }

            // Set-Location, the core remembers it for the drive, this is handy
            A.Psf.Engine.SessionState.Path.SetLocation(Kit.EscapeWildcard(Explorer.Location));

            //! path is used for Set-Location on Invoking()
            Title           = "Items: " + Explorer.Location;
            CurrentLocation = Explorer.Location;             //????

            if (info2.Provider.ImplementingType == typeof(FileSystemProvider))
            {
                UseSortGroups = true;
                Highlighting  = PanelHighlighting.Full;

                // _090929_061740 Before Far 2.0.1145 we used to sync the current directory to
                // the PS location. Now it is not needed because Far does not do that any more.
            }
            else
            {
                UseSortGroups = false;
                Highlighting  = PanelHighlighting.Default;
            }
        }
Exemple #3
0
        ///
        public PathInfoEx(string path)
        {
            var core = A.Psf.Engine.SessionState.Path;

            if (string.IsNullOrEmpty(path) || path == ".")
            {
                _PathInfo = core.CurrentLocation;
            }
            else
            {
                // 3 times faster than push/set/pop location; NB: it is slow anyway
                _PathInfo = core.GetResolvedPSPathFromPSPath(Kit.EscapeWildcard(path))[0];
            }
        }
Exemple #4
0
        /// <inheritdoc/>
        public override void DoRenameFile(RenameFileEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            if (!(args.Parameter is string newName))
            {
                throw new InvalidOperationException(Res.ParameterString);
            }

            // workaround; Rename-Item has no -LiteralPath; e.g. z`z[z.txt is a big problem
            string src = Kit.EscapeWildcard(My.PathEx.Combine(Location, args.File.Name));

            A.Psf.Engine.InvokeProvider.Item.Rename(src, newName);
        }
Exemple #5
0
        /// <inheritdoc/>
        public override void AcceptFiles(AcceptFilesEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            // that source
            var that = args.Explorer as PropertyExplorer;

            if (that == null)
            {
                if (args.UI)
                {
                    A.Message(Res.UnknownFileSource);
                }
                args.Result = JobResult.Ignore;
                return;
            }

            // names
            List <string> names = A.FileNameList(args.Files);

            //! gotchas in {Copy|Move}-ItemProperty:
            //! *) -Name takes a single string only? (help: yes (copy), no (move) - odd!)
            //! *) Names can't be pipelined (help says they can)
            //! so, use provider directly (no confirmation)
            string source = Kit.EscapeWildcard(that.ItemPath);
            string target = Kit.EscapeWildcard(this.ItemPath);

            if (args.Move)
            {
                foreach (string name in names)
                {
                    A.Psf.Engine.InvokeProvider.Property.Move(source, name, target, name);
                }
            }
            else
            {
                foreach (string name in names)
                {
                    A.Psf.Engine.InvokeProvider.Property.Copy(source, name, target, name);
                }
            }
        }
Exemple #6
0
        /// <inheritdoc/>
        public override void CloneFile(CloneFileEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            if (!(args.Parameter is string newName))
            {
                throw new InvalidOperationException(Res.ParameterString);
            }

            string src = Kit.EscapeWildcard(ItemPath);

            A.Psf.Engine.InvokeProvider.Property.Copy(src, args.File.Name, src, newName);

            args.PostName = newName;
        }
Exemple #7
0
        /// <inheritdoc/>
        public override void DoCloneFile(CloneFileEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            if (!(args.Parameter is string newName))
            {
                throw new InvalidOperationException(Res.ParameterString);
            }

            string source = Kit.EscapeWildcard(My.PathEx.Combine(Location, args.File.Name));
            string target = My.PathEx.Combine(Location, newName);

            A.Psf.Engine.InvokeProvider.Item.Copy(source, target, false, CopyContainers.CopyTargetContainer);

            args.PostName = newName;
        }
Exemple #8
0
        /// <summary>
        /// Sync provider location and current directory with Far state.
        /// </summary>
        /// <remarks>
        /// Returned system path (if not null) must be restored by a called.
        /// </remarks>
        internal string SyncPaths()
        {
            // don't on running
            if (IsRunning)
            {
                return(null);
            }

            // don't on no panels mode
            IPanel panel = Far.Api.Panel;

            if (panel == null)
            {
                return(null);
            }

            // at first get both paths: for the current system directory and provider location
            string directory = Far.Api.CurrentDirectory;
            string location  = null;

            if (panel.IsPlugin)
            {
                Panel plugin = panel as Panel;
                if (plugin != null)
                {
                    var itemPanel = plugin as ItemPanel;
                    if (itemPanel != null)
                    {
                        location = itemPanel.Explorer.Location;
                    }
                    else
                    {
                        FolderTree folderTree = plugin as FolderTree;
                        if (folderTree != null)
                        {
                            location = panel.CurrentDirectory;
                            if (location == "*")                             //_130117_234326
                            {
                                location = directory;
                            }
                        }
                    }
                }
            }

            // to set yet unknown location to the directory
            if (location == null)
            {
                location = directory;
            }

            // set the current provider location; let's do it first, in case of failure
            // we can skip directory setting/restoring in cases when they are the same.
            bool okLocation = true;

            try
            {
                //! Parameter is wildcard. Test: enter into a container "[]" and invoke a command.
                Engine.SessionState.Path.SetLocation(Kit.EscapeWildcard(location));

                // drop failure info
                _failedInvokingLocationNew = null;
                _failedInvokingLocationOld = null;
            }
            catch
            {
                okLocation = false;

                // get the current
                string currentLocation = Engine.SessionState.Path.CurrentLocation.Path;

                // ask a user if he has not told to ignore this pair
                if (location != _failedInvokingLocationNew || currentLocation != _failedInvokingLocationOld)
                {
                    string message = string.Format(null, @"
Cannot set the current location to
{0}

Continue with this current location?
{1}
", location, currentLocation);

                    switch (Far.Api.Message(message, Res.Me, MessageOptions.GuiOnMacro | MessageOptions.AbortRetryIgnore | MessageOptions.Warning | MessageOptions.LeftAligned))
                    {
                    case 1:
                        break;

                    case 2:
                        _failedInvokingLocationNew = location;
                        _failedInvokingLocationOld = currentLocation;
                        break;

                    default:
                        if (Far.Api.MacroState != MacroState.None)
                        {
                            Far.Api.UI.Break();
                        }
                        throw;
                    }
                }
            }

            // do not try failed
            if (!okLocation && location == directory)
            {
                return(null);
            }

            // get the current directory to be restored by a caller
            string currentDirectory = Directory.GetCurrentDirectory();

            // set the current directory to the active path to avoid confusions [_090929_061740]
            try
            {
                // try to set
                Directory.SetCurrentDirectory(directory);

                // drop failure info
                _failedInvokingDirectoryNew = null;
                _failedInvokingDirectoryOld = null;
            }
            catch
            {
                // ask a user if he has not told to ignore this pair
                if (directory != _failedInvokingDirectoryNew || currentDirectory != _failedInvokingDirectoryOld)
                {
                    string message = string.Format(null, @"
Cannot set the current directory to
{0}

Continue with this current directory?
{1}
", directory, currentDirectory);

                    switch (Far.Api.Message(message, Res.Me, MessageOptions.GuiOnMacro | MessageOptions.AbortRetryIgnore | MessageOptions.Warning | MessageOptions.LeftAligned))
                    {
                    case 1:
                        currentDirectory = null;
                        break;

                    case 2:
                        currentDirectory            = null;
                        _failedInvokingDirectoryNew = directory;
                        _failedInvokingDirectoryOld = currentDirectory;
                        break;

                    default:
                        if (Far.Api.MacroState != MacroState.None)
                        {
                            Far.Api.UI.Break();
                        }
                        throw;
                    }
                }
            }

            // to be restored by a caller
            return(currentDirectory);
        }
Exemple #9
0
        /// <inheritdoc/>
        public override IEnumerable <FarFile> GetFiles(GetFilesEventArgs args)
        {
            var result = new List <FarFile>();

            if (args == null)
            {
                return(result);
            }

            try
            {
                //! get properties
                // - Using -LiteralPath is a problem, e.g. Registry: returns nothing.
                // - Script is used for PS conversion of property values to string.
                // - Script has to ignore a property with empty name (if any, can be in Registry).
                // - If PS* included then they can't be found by `gp <path> <name>`;
                // so, don't add, they are noisy anyway (even if marked system or hidden).

                // get property bag 090409
                Collection <PSObject> bag = A.Psf.Engine.InvokeProvider.Property.Get(Kit.EscapeWildcard(ItemPath), null);

                // filter
                var filter = new List <string>(5);
                filter.Add("PSChildName");
                filter.Add("PSDrive");
                filter.Add("PSParentPath");
                filter.Add("PSPath");
                filter.Add("PSProvider");

                // add
                foreach (PSObject o in bag)
                {
                    foreach (PSPropertyInfo pi in o.Properties)
                    {
                        // skip empty ?? still needed?
                        string name = pi.Name;
                        if (string.IsNullOrEmpty(name))
                        {
                            continue;
                        }

                        // filter and shrink filter
                        int i = filter.IndexOf(name);
                        if (i >= 0)
                        {
                            filter.RemoveAt(i);
                            continue;
                        }

                        // create file
                        SetFile file = new SetFile()
                        {
                            Name       = name,
                            IsReadOnly = !pi.IsSettable,
                            Data       = pi,
                            // set its value
                            Description = Converter.FormatValue(pi.Value, Settings.Default.FormatEnumerationLimit)
                        };

                        // add
                        result.Add(file);
                    }
                }
            }
            catch (RuntimeException error)
            {
                if (args.UI)
                {
                    A.Message(error.Message);
                }
            }

            return(result);
        }
Exemple #10
0
        /// <inheritdoc/>
        public override void DeleteFiles(DeleteFilesEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            // to ask
            bool confirm = args.UI && 0 != (long)Far.Api.GetSetting(FarSetting.Confirmations, "Delete");

            // names to be deleted
            List <string> names = A.FileNameList(args.Files);

            //! Registry: workaround: (default)
            if (Provider.ImplementingType == typeof(RegistryProvider))
            {
                for (int i = names.Count; --i >= 0;)
                {
                    if (Kit.Equals(names[i], "(default)"))
                    {
                        // remove or not
                        if (!confirm || 0 == Far.Api.Message("Delete the (default) property", Res.Delete, MessageOptions.YesNo))
                        {
                            A.Psf.Engine.InvokeProvider.Property.Remove(Kit.EscapeWildcard(ItemPath), string.Empty);
                        }

                        // remove from the list in any case
                        names.RemoveAt(i);
                        break;
                    }
                }

                // done?
                if (names.Count == 0)
                {
                    return;
                }
            }

            using (var ps = A.Psf.NewPowerShell())
            {
                ps.AddCommand("Remove-ItemProperty")
                .AddParameter("LiteralPath", ItemPath)
                .AddParameter(Word.Name, names)
                .AddParameter(Prm.Force)
                .AddParameter(Prm.ErrorAction, ActionPreference.Continue);

                if (confirm)
                {
                    ps.AddParameter(Prm.Confirm);
                }

                ps.Invoke();

                // ?? V2 CTP3 bug: Registry: Remove-ItemProperty -Confirm fails on 'No':
                // Remove-ItemProperty : Property X does not exist at path HKEY_CURRENT_USER\Y
                // There is no workaround added yet. Submitted: MS Connect #484664.
                if (ps.Streams.Error.Count > 0)
                {
                    args.Result = JobResult.Incomplete;
                    if (args.UI)
                    {
                        A.ShowError(ps);
                    }
                }
            }
        }