PowerShellUtils/Commands/Bfs/BfsCommand.cs
using System;
using System.Collections.Generic; using System.IO; using System.Linq; using System.Management.Automation; using System.Threading; namespace PowerShellStandardModule1.Commands.Bfs; [Cmdlet(verbName: VerbsCommon.Get, nounName: "Bfs")] [Alias("Bfs")] [OutputType([typeof(FileInfo), typeof(DirectoryInfo)])] public class BfsCommand : PSCmdlet { [Parameter( Mandatory = false, Position = 0, HelpMessage = "The pattern to search for. Follows same conventions as other PowerShell commands." )] public string Pattern = "*"; private string? _startingDirectory; [Parameter( Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The directory to start the search from. Defaults to the current directory." )] public string StartingDirectory { get => _startingDirectory ?? CurrentProviderLocation("FileSystem") .ProviderPath; set => _startingDirectory = value; } [Parameter(HelpMessage = "Enable to be have case sensitive search.")] public SwitchParameter CaseSensitive; [Parameter(HelpMessage = "Enable to receive files in addition to directories.")] public SwitchParameter File; [Parameter(HelpMessage = "Max depth to search. Defaults to 10.")] public int Depth { get; set; } = 10; [Parameter( HelpMessage = "How many results to take before stopping. Defaults to 1. Negative numbers are rounded to 0." )] public int First = 1; [Parameter( HelpMessage = "The maximum amount of items to process, regardless if they match the pattern. Defaults to int32 max. Negative numbers rounded to 0." )] public int Limit = int.MaxValue; private CancellationTokenSource _cts = null!; protected override void BeginProcessing() { _cts = new CancellationTokenSource(); } protected override void ProcessRecord() { var ignoreCase = !CaseSensitive; var runner = new BfsController( pattern: Pattern, startingDirectory: new DirectoryInfo(StartingDirectory), ignoreCase: ignoreCase, file: File, height: Depth, limit: Limit, take: First ); try { IEnumerable<PSObject> res = runner .Invoke(_cts.Token) .Select(x => new PSObject(x.Value)); foreach (var result in res) { WriteObject(result); } } catch (DirectoryNotFoundException e) { WriteError( new ErrorRecord( e, "DirectoryNotFound", ErrorCategory.ObjectNotFound, StartingDirectory ) ); } catch (OperationCanceledException) { var record = new InformationRecord( new { message = "Operation was cancelled.", directory = StartingDirectory, pattern = Pattern, caseSensitive = CaseSensitive }, "BfsCommand.OperationCancelled" ); WriteInformation(record); } catch (Exception e) { WriteError( new ErrorRecord( e, "UnknownError", ErrorCategory.NotSpecified, StartingDirectory ) ); } } protected override void StopProcessing() { _cts.Cancel(); } } |