// rough proof that when choosing random K items out of N items // each item has got K/N probability of being included in the final list // // probability that a particular item in chosenListItems is NOT going to be replaced // when processing I-th input item [assumes I > K]: // P_one_step(I) = 1 - ((K / I) * ((K - 1) / K) + ((I - K) / I) = (I - 1) / I // <--A--> <-----B-----> <-----C-----> // A - probability that I-th element is going to be replacing an element from chosenListItems // (see (1) in the code below) // B - probability that a particular element from chosenListItems is NOT going to be replaced // (see (2) in the code below) // C - probability that I-th element is NOT going to be replacing an element from chosenListItems // (see (1) in the code below) // // probability that a particular item in chosenListItems is NOT going to be replaced // when processing input items J through N [assumes J > K] // P_removal(J) = Multiply(for I = J to N) P(I) = // = ((J - 1) / J) * (J / (J + 1)) * ... * ((N - 2) / (N - 1)) * ((N - 1) / N) = // = (J - 1) / N // // probability that when processing an element it is going to be put into chosenListItems // P_insertion(I) = 1.0 when I <= K - see (3) in the code below // P_insertion(I) = K/N otherwise - see (1) in the code below // // probability that a given element is going to be a part of the final list // P_final(I) = P_insertion(I) * P_removal(max(I + 1, K + 1)) // [for I <= K] = 1.0 * ((K + 1) - 1) / N = K / N // [otherwise] = (K / I) * ((I + 1) - 1) / N = K / N // // which proves that P_final(I) = K / N for all values of I. QED. /// <summary> /// This method implements the ProcessRecord method for get-random command. /// </summary> protected override void ProcessRecord() { if (EffectiveParameterSet == MyParameterSet.RandomListItem) { if (ParameterSetName == ShuffleParameterSet) { // this allows for $null to be in an array passed to InputObject foreach (object item in InputObject ?? _nullInArray) { _chosenListItems.Add(item); } } else { foreach (object item in InputObject ?? _nullInArray) { // (3) if (_numberOfProcessedListItems < Count) { Debug.Assert(_chosenListItems.Count == _numberOfProcessedListItems, "Initial K elements should all be included in chosenListItems"); _chosenListItems.Add(item); } else { Debug.Assert(_chosenListItems.Count == Count, "After processing K initial elements, the length of chosenItems should stay equal to K"); // (1) if (Generator.Next(_numberOfProcessedListItems + 1) < Count) { // (2) int indexToReplace = Generator.Next(_chosenListItems.Count); _chosenListItems[indexToReplace] = item; } } _numberOfProcessedListItems++; } } } }
internal bool ShouldProcess() { Dbg.Assert(this.MethodSubject != null, "MethodSubject property should be initialized before starting main job processing"); if (!this.JobContext.CmdletInvocationContext.CmdletDefinitionContext.ClientSideShouldProcess) { return(true); } bool shouldProcess; if (!this.JobContext.SupportsShouldProcess) { shouldProcess = true; this.WriteVerboseStartOfCimOperation(); } else { string target = this.MethodSubject; string action = this.MethodName; CimResponseType cimResponseType = this.ShouldProcess(target, action); switch (cimResponseType) { case CimResponseType.Yes: case CimResponseType.YesToAll: shouldProcess = true; break; default: shouldProcess = false; break; } } if (!shouldProcess) { this.SetCompletedJobState(JobState.Completed, null); } return(shouldProcess); }
internal override void StartJob() { lock (_jobStateLock) { if (_jobWasStopped) { this.SetCompletedJobState(JobState.Stopped, null); return; } Dbg.Assert(!_alreadyReachedCompletedState, "Job shouldn't reach completed state, before ThrottlingJob has a chance to register for job-completed/failed events"); TerminatingErrorTracker tracker = TerminatingErrorTracker.GetTracker(this.JobContext.CmdletInvocationInfo); if (tracker.IsSessionTerminated(this.JobContext.Session)) { this.SetCompletedJobState(JobState.Failed, new OperationCanceledException()); return; } if (!_jobWasStarted) { _jobWasStarted = true; this.SetJobState(JobState.Running); } } // This invocation can block (i.e. by calling Job.ShouldProcess) and wait for pipeline thread to unblock it // Therefore we have to do the invocation outside of the pipeline thread. ThreadPool.QueueUserWorkItem(delegate { this.ExceptionSafeWrapper(delegate { IObservable <T> observable = this.GetCimOperation(); if (observable != null) { observable.Subscribe(this); } }); }); }
HandleIncomingProgressRecord(Int64 sourceId, ProgressRecord record) { Dbg.Assert(record != null, "record should not be null"); if (_pendingProgress == null) { Dbg.Assert(_progPane == null, "If there is no data struct, there shouldn't be a pane, either."); _pendingProgress = new PendingProgress(); } _pendingProgress.Update(sourceId, record); if (_progPane == null) { // This is the first time we've received a progress record. Create a pane to show it, and // then show it. _progPane = new ProgressPane(this); } _progPane.Show(_pendingProgress); }
EvictNode() { ArrayList listWhereFound = null; int indexWhereFound = -1; ProgressNode oldestNode = FindOldestLeafmostNode(out listWhereFound, out indexWhereFound); if (oldestNode == null) { // Well that's a surprise. There's got to be at least one node there that's older than 0. Dbg.Assert(false, "Must be an old node in the tree somewhere"); // We'll just pick the root node, then. RemoveNode(_topLevelNodes, 0); } else { RemoveNode(listWhereFound, indexWhereFound); } }
internal static Type GetElementType(Type arrayType) { Dbg.Assert(arrayType != null, "Caller should verify arrayType != null"); Dbg.Assert(arrayType.IsArray, "Caller should verify arrayType.IsArray"); // MOF syntax from Appendix A of DSP0004 doesn't allow expressing // of 1) nested arrays and 2) multi-dimensional arrays // (see production for "array" and how this production is used in // other productions like "propertyDeclaration" or "parameter") if (arrayType.GetArrayRank() != 1) { return(null); } Type elementType = arrayType.GetElementType(); if (elementType.IsArray) { return(null); } return(elementType); }
HandleIncomingProgressRecord(Int64 sourceId, ProgressRecord record) { Dbg.Assert(record != null, "record should not be null"); if (_pendingProgress == null) { Dbg.Assert(_progPane == null, "If there is no data struct, there shouldn't be a pane, either."); _pendingProgress = new PendingProgress(); } _pendingProgress.Update(sourceId, record); if (_progPane == null) { // This is the first time we've received a progress record // Create a progress pane // Set up a update flag // Create a timer for updating the flag _progPane = new ProgressPane(this); if (_progPaneUpdateTimer == null) { // Show a progress pane at the first time we've received a progress record progPaneUpdateFlag = 1; // The timer will be auto restarted every 'UpdateTimerThreshold' ms _progPaneUpdateTimer = new Timer(new TimerCallback(ProgressPaneUpdateTimerElapsed), null, UpdateTimerThreshold, UpdateTimerThreshold); } } if (Interlocked.CompareExchange(ref progPaneUpdateFlag, 0, 1) == 1 || record.RecordType == ProgressRecordType.Completed) { // Update the progress pane only when the timer set up the update flag or WriteProgress is completed. // As a result, we do not block WriteProgress and whole script and eliminate unnecessary console locks and updates. _progPane.Show(_pendingProgress); } }
/// <summary> /// Processes records from the input pipeline. /// For each input object, the command either generate the Catalog or /// Validates the existing Catalog /// </summary> protected override void ProcessRecord() { // // this cannot happen as we have specified the Path // property to be mandatory parameter // Dbg.Assert((CatalogFilePath != null) && (CatalogFilePath.Length > 0), "CatalogCommands: Param binder did not bind catalogFilePath"); Collection <string> paths = new Collection <string>(); if (Path != null) { foreach (string p in Path) { foreach (PathInfo tempPath in SessionState.Path.GetResolvedPSPathFromPSPath(p)) { if (ShouldProcess(tempPath.ProviderPath)) { paths.Add(tempPath.ProviderPath); } } } } // We add 'paths.Count > 0' to support 'ShouldProcess()' if (paths.Count > 0) { string drive = null; // resolve catalog destination Path if (!SessionState.Path.IsPSAbsolute(catalogFilePath, out drive) && !System.IO.Path.IsPathRooted(catalogFilePath)) { catalogFilePath = SessionState.Path.GetUnresolvedProviderPathFromPSPath(catalogFilePath); } PerformAction(paths, catalogFilePath); } }
/// <summary> /// Take an enumeration of modules and only return those that match a specification /// in the given specification table, or have no corresponding entry in the specification table. /// </summary> /// <param name="modules">The modules to filter by specification match.</param> /// <param name="moduleSpecificationTable">The specification lookup table to filter the modules on.</param> /// <returns>The modules that match their corresponding table entry, or which have no table entry.</returns> private static IEnumerable <PSModuleInfo> FilterModulesForSpecificationMatch( IEnumerable <PSModuleInfo> modules, IDictionary <string, ModuleSpecification> moduleSpecificationTable) { Dbg.Assert(moduleSpecificationTable != null, $"Caller to verify that {nameof(moduleSpecificationTable)} is not null"); Dbg.Assert(moduleSpecificationTable.Count != 0, $"Caller to verify that {nameof(moduleSpecificationTable)} is not empty"); foreach (PSModuleInfo module in modules) { IEnumerable <ModuleSpecification> candidateModuleSpecs = GetCandidateModuleSpecs(moduleSpecificationTable, module); // Modules with table entries only get returned if they match them // We skip the name check since modules have already been prefiltered base on the moduleSpec path/name foreach (ModuleSpecification moduleSpec in candidateModuleSpecs) { if (ModuleIntrinsics.IsModuleMatchingModuleSpec(module, moduleSpec, skipNameCheck: true)) { yield return(module); } } } }
public override void OnNext(CimMethodResultBase item) { this.ExceptionSafeWrapper( delegate { var methodResult = item as CimMethodResult; if (methodResult != null) { this.OnNext(methodResult); return; } var streamedResult = item as CimMethodStreamedResult; if (streamedResult != null) { this.OnNext(streamedResult); return; } Dbg.Assert(false, "CimMethodResultBase has to be either a CimMethodResult or CimMethodStreamedResult"); }); }
internal CimCmdletInvocationContext( CimCmdletDefinitionContext cmdletDefinitionContext, Cmdlet cmdlet, string namespaceOverride) { this.CmdletDefinitionContext = cmdletDefinitionContext; this.NamespaceOverride = namespaceOverride; // Cmdlet might have a shorter lifespan than CimCmdletInvocationContext // - we need to extract information out of Cmdlet to extend information's lifespan this.CmdletInvocationInfo = cmdlet.MyInvocation; var runtime = cmdlet.CommandRuntime as MshCommandRuntime; Dbg.Assert(runtime != null, "CIM cmdlets should only be run from within PS runtime"); this.DebugActionPreference = runtime.DebugPreference; WarnAboutUnsupportedActionPreferences( cmdlet, this.DebugActionPreference, "Debug", inquireMessageGetter: () => CmdletizationResources.CimCmdletAdapter_DebugInquire, stopMessageGetter: () => string.Empty); this.WarningActionPreference = runtime.WarningPreference; WarnAboutUnsupportedActionPreferences( cmdlet, this.WarningActionPreference, "WarningAction", inquireMessageGetter: () => CmdletizationResources.CimCmdletAdapter_WarningInquire, stopMessageGetter: () => CmdletizationResources.CimCmdletAdapter_WarningStop); this.VerboseActionPreference = runtime.VerbosePreference; this.ErrorActionPreference = runtime.ErrorAction; this.ShouldProcessOptimization = runtime.CalculatePossibleShouldProcessOptimization(); }
ResetProgress() { // destroy the data structures representing outstanding progress records // take down and destroy the progress display // If we have multiple runspaces on the host then any finished pipeline in any runspace will lead to call 'ResetProgress' // so we need the lock lock (_instanceLock) { if (_progPaneUpdateTimer != null) { // Stop update a progress pane and destroy timer _progPaneUpdateTimer.Dispose(); _progPaneUpdateTimer = null; } // We don't set 'progPaneUpdateFlag = 0' here, because: // 1. According to MSDN, the timer callback can occur after the Dispose() method has been called. // So we cannot guarantee the flag is truly set to 0. // 2. When creating a new timer in 'HandleIncomingProgressRecord', we will set the flag to 1 anyway if (_progPane != null) { Dbg.Assert(_pendingProgress != null, "How can you have a progress pane and no backing data structure?"); _progPane.Hide(); _progPane = null; } _pendingProgress = null; if (SupportsVirtualTerminal && PSStyle.Instance.Progress.UseOSCIndicator) { // OSC sequence to turn off progress indicator // https://github.com/microsoft/terminal/issues/6700 Console.Write("\x1b]9;4;0\x1b\\"); } } }
FindOldestLeafmostNodeHelper(ArrayList treeToSearch, out ArrayList listWhereFound, out int indexWhereFound) { listWhereFound = null; indexWhereFound = -1; FindOldestNodeVisitor v = new FindOldestNodeVisitor(); NodeVisitor.VisitNodes(treeToSearch, v); listWhereFound = v.ListWhereFound; indexWhereFound = v.IndexWhereFound; #if DEBUG || ASSERTIONS_TRACE if (v.FoundNode == null) { Dbg.Assert(listWhereFound == null, "list should be null when no node found"); Dbg.Assert(indexWhereFound == -1, "index should indicate no node found"); Dbg.Assert(_topLevelNodes.Count == 0, "if there is no oldest node, then the tree must be empty"); Dbg.Assert(_nodeCount == 0, "if there is no oldest node, then the tree must be empty"); } #endif return(v.FoundNode); }
public virtual IEnumerable <NotFoundError> GetNotFoundErrors_IfThisIsTheOnlyFilter() { switch (this.BehaviorOnNoMatch) { case BehaviorOnNoMatch.ReportErrors: if (this.HadMatches) { return(Enumerable.Empty <NotFoundError>()); } else { return(new[] { new NotFoundError() }); } case BehaviorOnNoMatch.SilentlyContinue: return(Enumerable.Empty <NotFoundError>()); case BehaviorOnNoMatch.Default: default: Dbg.Assert(false, "BehaviorOnNoMatch.Default should be handled by derived classes"); return(Enumerable.Empty <NotFoundError>()); } }
VisitNodes(ArrayList nodes, NodeVisitor v) { if (nodes == null) { return; } for (int i = 0; i < nodes.Count; ++i) { ProgressNode node = (ProgressNode)nodes[i]; Dbg.Assert(node != null, "nodes should not contain null elements"); if (!v.Visit(node, nodes, i)) { return; } if (node.Children != null) { VisitNodes(node.Children, v); } } }
internal static CimJobException CreateFromAnyException( string jobDescription, CimJobContext jobContext, Exception inner) { Dbg.Assert(!string.IsNullOrEmpty(jobDescription), "Caller should verify jobDescription != null"); Dbg.Assert(jobContext != null, "Caller should verify jobContext != null"); Dbg.Assert(inner != null, "Caller should verify inner != null"); CimException cimException = inner as CimException; if (cimException != null) { return(CreateFromCimException(jobDescription, jobContext, cimException)); } string message = BuildErrorMessage(jobDescription, jobContext, inner.Message); CimJobException cimJobException = new CimJobException(message, inner); var containsErrorRecord = inner as IContainsErrorRecord; if (containsErrorRecord != null) { cimJobException.InitializeErrorRecord( jobContext, errorId: "CimJob_" + containsErrorRecord.ErrorRecord.FullyQualifiedErrorId, errorCategory: containsErrorRecord.ErrorRecord.CategoryInfo.Category); } else { cimJobException.InitializeErrorRecord( jobContext, errorId: "CimJob_" + inner.GetType().Name, errorCategory: ErrorCategory.NotSpecified); } return(cimJobException); }
Render(ArrayList strCollection, int indentation, int maxWidth, PSHostRawUserInterface rawUI) { Dbg.Assert(strCollection != null, "strCollection should not be null"); Dbg.Assert(indentation >= 0, "indentation is negative"); Dbg.Assert(this.RecordType != ProgressRecordType.Completed, "should never render completed records"); switch (Style) { case RenderStyle.FullPlus: RenderFull(strCollection, indentation, maxWidth, rawUI, isFullPlus: true); break; case RenderStyle.Full: RenderFull(strCollection, indentation, maxWidth, rawUI, isFullPlus: false); break; case RenderStyle.Compact: RenderCompact(strCollection, indentation, maxWidth, rawUI); break; case RenderStyle.Minimal: RenderMinimal(strCollection, indentation, maxWidth, rawUI); break; case RenderStyle.Ansi: RenderAnsi(strCollection, indentation, maxWidth); break; case RenderStyle.Invisible: // do nothing break; default: Dbg.Assert(false, "unrecognized RenderStyle value"); break; } }
private static string GetMatchConditionForEqualityOperator(string propertyName, object propertyValue) { string condition; // comparison of 'char' is case-sensitive in WQL (comparison of 'string' is case-insensitive) if (propertyValue is char) { char c = (char)propertyValue; char lowerCase = char.ToLowerInvariant(c); char upperCase = char.ToUpperInvariant(c); string lowerCaseLiteral = CimQuery.ObjectToWqlLiteral(lowerCase); string upperCaseLiteral = CimQuery.ObjectToWqlLiteral(upperCase); Dbg.Assert(!string.IsNullOrWhiteSpace(lowerCaseLiteral), "All characters are assumed to have valid WQL literals (lower)"); Dbg.Assert(!string.IsNullOrWhiteSpace(upperCaseLiteral), "All characters are assumed to have valid WQL literals (upper)"); condition = string.Format( CultureInfo.InvariantCulture, "(({0} = {1}) OR ({0} = {2}))", propertyName, lowerCaseLiteral, upperCaseLiteral); return(condition); } string wqlLiteral = CimQuery.ObjectToWqlLiteral(propertyValue); if (string.IsNullOrWhiteSpace(wqlLiteral)) { return(null); } condition = string.Format( CultureInfo.InvariantCulture, "({0} = {1})", propertyName, wqlLiteral); return(condition); }
WrappedDeserializer(DataFormat dataFormat, string streamName, TextReader input) : base(dataFormat, streamName) { Dbg.Assert(input != null, "input should have a value"); // If the data format is none - do nothing... if (dataFormat == DataFormat.None) { return; } textReader = input; _firstLine = textReader.ReadLine(); if (String.Compare(_firstLine, Serialization.XmlCliTag, StringComparison.OrdinalIgnoreCase) == 0) { // format should be XML dataFormat = DataFormat.XML; } switch (format) { case DataFormat.XML: _xmlReader = XmlReader.Create(textReader, new XmlReaderSettings { XmlResolver = null }); _xmlDeserializer = new Deserializer(_xmlReader); break; case DataFormat.Text: default: // do nothing; we'll just read from the TextReader break; } }
private void SleepAndRetry() { int tmpRandomDelay = _random.Next(0, _sleepAndRetryDelayRangeMs); int delay = MinRetryDelayMs + _sleepAndRetryExtraDelayMs + tmpRandomDelay; _sleepAndRetryExtraDelayMs = _sleepAndRetryDelayRangeMs - tmpRandomDelay; if (_sleepAndRetryDelayRangeMs < MaxRetryDelayMs) { _sleepAndRetryDelayRangeMs *= 2; } string verboseMessage = string.Format( CultureInfo.InvariantCulture, CmdletizationResources.CimJob_SleepAndRetryVerboseMessage, this.JobContext.CmdletInvocationInfo.InvocationName, this.JobContext.Session.ComputerName ?? "localhost", delay / 1000.0); this.WriteVerbose(verboseMessage); lock (_jobStateLock) { if (_jobWasStopped) { this.SetCompletedJobState(JobState.Stopped, null); } else { Dbg.Assert(_sleepAndRetryTimer == null, "There should be only 1 active _sleepAndRetryTimer"); _sleepAndRetryTimer = new Timer( state: null, dueTime: delay, period: Timeout.Infinite, callback: SleepAndRetry_OnWakeup); } } }
/// <summary> /// Take an enumeration of modules and only return those that match a specification /// in the given specification table, or have no corresponding entry in the specification table. /// </summary> /// <param name="modules">The modules to filter by specification match.</param> /// <param name="moduleSpecificationTable">The specification lookup table to filter the modules on.</param> /// <returns>The modules that match their corresponding table entry, or which have no table entry.</returns> private static IEnumerable <PSModuleInfo> FilterModulesForSpecificationMatch( IEnumerable <PSModuleInfo> modules, IDictionary <string, ModuleSpecification> moduleSpecificationTable) { Dbg.Assert(moduleSpecificationTable != null, $"Caller to verify that {nameof(moduleSpecificationTable)} is not null"); Dbg.Assert(moduleSpecificationTable.Count != 0, $"Caller to verify that {nameof(moduleSpecificationTable)} is not empty"); foreach (PSModuleInfo module in modules) { // No table entry means we return the module if (!moduleSpecificationTable.TryGetValue(module.Name, out ModuleSpecification moduleSpecification)) { yield return(module); continue; } // Modules with table entries only get returned if they match them if (ModuleIntrinsics.IsModuleMatchingModuleSpec(module, moduleSpecification)) { yield return(module); } } }
/// <summary> /// All calls to the Runspace to execute a command line must be done with this function, which properly synchronizes /// access to the running pipeline between the main thread and the break handler thread. This synchronization is /// necessary so that executions can be aborted with Ctrl-C (including evaluation of the prompt and collection of /// command-completion candidates. /// /// On any given Executor instance, ExecuteCommand should be called at most once at a time by any one thread. It is NOT /// reentrant. /// </summary> /// <param name="command"> /// The command line to be executed. Must be non-null. /// </param> /// <param name="exceptionThrown"> /// Receives the Exception thrown by the execution of the command, if any. If no exception is thrown, then set to null. /// Can be tested to see if the execution was successful or not. /// </param> /// <param name="options"> /// options to govern the execution /// </param> /// <returns> /// the object stream resulting from the execution. May be null. /// </returns> internal Collection <PSObject> ExecuteCommand(string command, out Exception exceptionThrown, ExecutionOptions options) { Dbg.Assert(!String.IsNullOrEmpty(command), "command should have a value"); // Experimental: // Check for implicit remoting commands that can be batched, and execute as batched if able. if (ExperimentalFeature.IsEnabled("PSImplicitRemotingBatching")) { var addOutputter = ((options & ExecutionOptions.AddOutputter) > 0); if (addOutputter && !_parent.RunspaceRef.IsRunspaceOverridden && _parent.RunspaceRef.Runspace.ExecutionContext.Modules != null && _parent.RunspaceRef.Runspace.ExecutionContext.Modules.IsImplicitRemotingModuleLoaded && Utils.TryRunAsImplicitBatch(command, _parent.RunspaceRef.Runspace)) { exceptionThrown = null; return(null); } } Pipeline tempPipeline = CreatePipeline(command, (options & ExecutionOptions.AddToHistory) > 0); return(ExecuteCommandHelper(tempPipeline, out exceptionThrown, options)); }
WrappedSerializer(DataFormat dataFormat, string streamName, TextWriter output) : base(dataFormat, streamName) { Dbg.Assert(output != null, "output should have a value"); textWriter = output; switch (format) { case DataFormat.XML: XmlWriterSettings settings = new XmlWriterSettings(); settings.CheckCharacters = false; settings.OmitXmlDeclaration = true; _xmlWriter = XmlWriter.Create(textWriter, settings); _xmlSerializer = new Serializer(_xmlWriter); break; case DataFormat.Text: default: // do nothing; we'll just write to the TextWriter // or discard it. break; } }
/// <summary> /// Process record /// </summary> protected override void ProcessRecord() { IReadOnlyList <Runspace> results; if ((ParameterSetName == GetRunspaceCommand.NameParameterSet) && ((Name == null) || Name.Length == 0)) { results = GetRunspaceUtils.GetAllRunspaces(); } else { switch (ParameterSetName) { case GetRunspaceCommand.NameParameterSet: results = GetRunspaceUtils.GetRunspacesByName(Name); break; case GetRunspaceCommand.IdParameterSet: results = GetRunspaceUtils.GetRunspacesById(Id); break; case GetRunspaceCommand.InstanceIdParameterSet: results = GetRunspaceUtils.GetRunspacesByInstanceId(InstanceId); break; default: Dbg.Assert(false, "Unknown parameter set in GetRunspaceCommand"); results = new List <Runspace>().AsReadOnly(); break; } } foreach (Runspace runspace in results) { WriteObject(runspace); } }
private void ParseHelper(string[] args) { Dbg.Assert(args != null, "Argument 'args' to ParseHelper should never be null"); bool noexitSeen = false; for (int i = 0; i < args.Length; ++i) { // Invariant culture used because command-line parameters are not localized. string switchKey = args[i].Trim().ToLowerInvariant(); if (String.IsNullOrEmpty(switchKey)) { continue; } if (!SpecialCharacters.IsDash(switchKey[0]) && switchKey[0] != '/') { // then its a file --i; ParseFile(args, ref i, noexitSeen); break; } // chop off the first character so that we're agnostic wrt specifying / or - // in front of the switch name. switchKey = switchKey.Substring(1); // chop off the second dash so we're agnostic wrt specifying - or -- if (!String.IsNullOrEmpty(switchKey) && SpecialCharacters.IsDash(switchKey[0])) { switchKey = switchKey.Substring(1); } // If version is in the commandline, don't continue to look at any other parameters if (MatchSwitch(switchKey, "version", "v")) { _showVersion = true; _showBanner = false; _noInteractive = true; _skipUserInit = true; _noExit = false; break; } else if (MatchSwitch(switchKey, "help", "h") || MatchSwitch(switchKey, "?", "?")) { _showHelp = true; _showExtendedHelp = true; _abortStartup = true; } else if (MatchSwitch(switchKey, "noexit", "noe")) { _noExit = true; noexitSeen = true; } else if (MatchSwitch(switchKey, "noprofile", "nop")) { _skipUserInit = true; } else if (MatchSwitch(switchKey, "nologo", "nol")) { _showBanner = false; } else if (MatchSwitch(switchKey, "noninteractive", "noni")) { _noInteractive = true; } else if (MatchSwitch(switchKey, "socketservermode", "so")) { _socketServerMode = true; } else if (MatchSwitch(switchKey, "servermode", "s")) { _serverMode = true; } else if (MatchSwitch(switchKey, "namedpipeservermode", "nam")) { _namedPipeServerMode = true; } else if (MatchSwitch(switchKey, "sshservermode", "sshs")) { _sshServerMode = true; } else if (MatchSwitch(switchKey, "interactive", "i")) { _noInteractive = false; } else if (MatchSwitch(switchKey, "configurationname", "config")) { ++i; if (i >= args.Length) { WriteCommandLineError( CommandLineParameterParserStrings.MissingConfigurationNameArgument); break; } _configurationName = args[i]; } else if (MatchSwitch(switchKey, "command", "c")) { if (!ParseCommand(args, ref i, noexitSeen, false)) { break; } } else if (MatchSwitch(switchKey, "windowstyle", "w")) { #if UNIX WriteCommandLineError( CommandLineParameterParserStrings.WindowStyleArgumentNotImplemented); break; #else ++i; if (i >= args.Length) { WriteCommandLineError( CommandLineParameterParserStrings.MissingWindowStyleArgument); break; } try { ProcessWindowStyle style = (ProcessWindowStyle)LanguagePrimitives.ConvertTo( args[i], typeof(ProcessWindowStyle), CultureInfo.InvariantCulture); ConsoleControl.SetConsoleMode(style); } catch (PSInvalidCastException e) { WriteCommandLineError( string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidWindowStyleArgument, args[i], e.Message)); break; } #endif } else if (MatchSwitch(switchKey, "file", "f")) { if (!ParseFile(args, ref i, noexitSeen)) { break; } } #if DEBUG // this option is useful when debugging ConsoleHost remotely using VS remote debugging, as you can only // attach to an already running process with that debugger. else if (MatchSwitch(switchKey, "wait", "w")) { // This does not need to be localized: its chk only ((ConsoleHostUserInterface)_hostUI).WriteToConsole("Waiting - type enter to continue:", false); _hostUI.ReadLine(); } // this option is useful for testing the initial InitialSessionState experience else if (MatchSwitch(switchKey, "iss", "iss")) { // Just toss this option, it was processed earlier... } // this option is useful for testing the initial InitialSessionState experience // this is independent of the normal wait switch because configuration processing // happens so early in the cycle... else if (MatchSwitch(switchKey, "isswait", "isswait")) { // Just toss this option, it was processed earlier... } else if (MatchSwitch(switchKey, "modules", "mod")) { if (ConsoleHost.DefaultInitialSessionState == null) { WriteCommandLineError( "The -module option can only be specified with the -iss option.", showHelp: true, showBanner: false); break; } ++i; int moduleCount = 0; // Accumulate the arguments to this script... while (i < args.Length) { string arg = args[i]; if (!string.IsNullOrEmpty(arg) && SpecialCharacters.IsDash(arg[0])) { break; } else { ConsoleHost.DefaultInitialSessionState.ImportPSModule(new string[] { arg }); moduleCount++; } ++i; } if (moduleCount < 1) { _hostUI.WriteErrorLine("No modules specified for -module option"); } } #endif else if (MatchSwitch(switchKey, "outputformat", "o") || MatchSwitch(switchKey, "of", "o")) { ParseFormat(args, ref i, ref _outFormat, CommandLineParameterParserStrings.MissingOutputFormatParameter); } else if (MatchSwitch(switchKey, "inputformat", "in") || MatchSwitch(switchKey, "if", "if")) { ParseFormat(args, ref i, ref _inFormat, CommandLineParameterParserStrings.MissingInputFormatParameter); } else if (MatchSwitch(switchKey, "executionpolicy", "ex") || MatchSwitch(switchKey, "ep", "ep")) { ParseExecutionPolicy(args, ref i, ref _executionPolicy, CommandLineParameterParserStrings.MissingExecutionPolicyParameter); } else if (MatchSwitch(switchKey, "encodedcommand", "e") || MatchSwitch(switchKey, "ec", "e")) { _wasCommandEncoded = true; if (!ParseCommand(args, ref i, noexitSeen, true)) { break; } } else if (MatchSwitch(switchKey, "encodedarguments", "encodeda") || MatchSwitch(switchKey, "ea", "ea")) { if (!CollectArgs(args, ref i)) { break; } } else if (MatchSwitch(switchKey, "settingsfile", "settings")) { ++i; if (i >= args.Length) { WriteCommandLineError( CommandLineParameterParserStrings.MissingSettingsFileArgument); break; } string configFile = null; try { configFile = NormalizeFilePath(args[i]); } catch (Exception ex) { string error = string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidSettingsFileArgument, args[i], ex.Message); WriteCommandLineError(error); break; } if (!System.IO.File.Exists(configFile)) { string error = string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.SettingsFileNotExists, configFile); WriteCommandLineError(error); break; } PowerShellConfig.Instance.SetSystemConfigFilePath(configFile); } #if STAMODE // explicit setting of the ApartmentState Not supported on NanoServer else if (MatchSwitch(switchKey, "sta", "s")) { if (_staMode.HasValue) { // -sta and -mta are mutually exclusive. WriteCommandLineError( CommandLineParameterParserStrings.MtaStaMutuallyExclusive); break; } _staMode = true; } // Win8: 182409 PowerShell 3.0 should run in STA mode by default..so, consequently adding the switch -mta. // Not deleting -sta for backward compatability reasons else if (MatchSwitch(switchKey, "mta", "mta")) { if (_staMode.HasValue) { // -sta and -mta are mutually exclusive. WriteCommandLineError( CommandLineParameterParserStrings.MtaStaMutuallyExclusive); break; } _staMode = false; } #endif else if (MatchSwitch(switchKey, "workingdirectory", "wo") || MatchSwitch(switchKey, "wd", "wd")) { ++i; if (i >= args.Length) { WriteCommandLineError( CommandLineParameterParserStrings.MissingWorkingDirectoryArgument); break; } _workingDirectory = args[i]; } else { // The first parameter we fail to recognize marks the beginning of the file string. --i; if (!ParseFile(args, ref i, noexitSeen)) { break; } } } if (_showHelp) { ShowHelp(); } if (_showBanner && !_showHelp) { DisplayBanner(); } Dbg.Assert( ((_exitCode == ConsoleHost.ExitCodeBadCommandLineParameter) && _abortStartup) || (_exitCode == ConsoleHost.ExitCodeSuccess), "if exit code is failure, then abortstartup should be true"); }
/// <summary> /// ProcessRecord method. /// </summary> protected override void ProcessRecord() { if (ParameterSetName.Equals("Xml", StringComparison.OrdinalIgnoreCase)) { foreach (XmlNode xmlNode in this.Xml) { ProcessXmlNode(xmlNode, string.Empty); } } else if ( (ParameterSetName.Equals("Path", StringComparison.OrdinalIgnoreCase) || (ParameterSetName.Equals("LiteralPath", StringComparison.OrdinalIgnoreCase)))) { // If any file not resolved, execution stops. this is to make consistent with select-string. List <string> fullresolvedPaths = new(); foreach (string fpath in Path) { if (_isLiteralPath) { string resolvedPath = GetUnresolvedProviderPathFromPSPath(fpath); fullresolvedPaths.Add(resolvedPath); } else { ProviderInfo provider; Collection <string> resolvedPaths = GetResolvedProviderPathFromPSPath(fpath, out provider); if (!provider.NameEquals(this.Context.ProviderNames.FileSystem)) { // Cannot open File error string message = StringUtil.Format(UtilityCommonStrings.FileOpenError, provider.FullName); InvalidOperationException e = new(message); ErrorRecord er = new(e, "ProcessingFile", ErrorCategory.InvalidOperation, fpath); WriteError(er); continue; } fullresolvedPaths.AddRange(resolvedPaths); } } foreach (string file in fullresolvedPaths) { ProcessXmlFile(file); } } else if (ParameterSetName.Equals("Content", StringComparison.OrdinalIgnoreCase)) { foreach (string xmlstring in Content) { XmlDocument xmlDocument; try { xmlDocument = (XmlDocument)LanguagePrimitives.ConvertTo(xmlstring, typeof(XmlDocument), CultureInfo.InvariantCulture); } catch (PSInvalidCastException invalidCastException) { this.WriteError(invalidCastException.ErrorRecord); continue; } this.ProcessXmlNode(xmlDocument, string.Empty); } } else { Dbg.Assert(false, "Unrecognized parameterset"); } }
/// <summary> /// Saves the current console info into a file. /// </summary> protected override void ProcessRecord() { // Get filename.. string file = GetFileName(); // if file is null or empty..prompt the user for filename if (string.IsNullOrEmpty(file)) { file = PromptUserForFile(); } // if file is still empty..write error and back out.. if (string.IsNullOrEmpty(file)) { PSArgumentException ae = PSTraceSource.NewArgumentException("file", ConsoleInfoErrorStrings.FileNameNotResolved); ThrowError(file, "FileNameNotResolved", ae, ErrorCategory.InvalidArgument); } if (WildcardPattern.ContainsWildcardCharacters(file)) { ThrowError(file, "WildCardNotSupported", PSTraceSource.NewInvalidOperationException(ConsoleInfoErrorStrings.ConsoleFileWildCardsNotSupported, file), ErrorCategory.InvalidOperation); } // Ofcourse, you cant write to a file from HKLM: etc.. string resolvedPath = ResolveProviderAndPath(file); // If resolvedPath is empty just return.. if (string.IsNullOrEmpty(resolvedPath)) { return; } // Check whether the file ends with valid extension if (!resolvedPath.EndsWith(StringLiterals.PowerShellConsoleFileExtension, StringComparison.OrdinalIgnoreCase)) { // file does not end with proper extension..create one.. resolvedPath = resolvedPath + StringLiterals.PowerShellConsoleFileExtension; } if (!ShouldProcess(this.Path)) // should this be resolvedPath? { return; } //check if destination file exists. if (File.Exists(resolvedPath)) { if (NoClobber) { string message = StringUtil.Format( ConsoleInfoErrorStrings.FileExistsNoClobber, resolvedPath, "NoClobber"); // prevents localization Exception uae = new UnauthorizedAccessException(message); ErrorRecord errorRecord = new ErrorRecord( uae, "NoClobber", ErrorCategory.ResourceExists, resolvedPath); // NOTE: this call will throw ThrowTerminatingError(errorRecord); } // Check if the file is read-only System.IO.FileAttributes attrib = System.IO.File.GetAttributes(resolvedPath); if ((attrib & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly) { if (Force) { RemoveFileThrowIfError(resolvedPath); // Note, we do not attempt to set read-only on the new file } else { ThrowError(file, "ConsoleFileReadOnly", PSTraceSource.NewArgumentException(file, ConsoleInfoErrorStrings.ConsoleFileReadOnly, resolvedPath), ErrorCategory.InvalidArgument); } } } try { if (this.Runspace != null) { this.Runspace.SaveAsConsoleFile(resolvedPath); } else if (InitialSessionState != null) { this.InitialSessionState.SaveAsConsoleFile(resolvedPath); } else { Dbg.Assert(false, "Both RunspaceConfiguration and InitialSessionState should not be null"); throw PSTraceSource.NewInvalidOperationException(ConsoleInfoErrorStrings.CmdletNotAvailable); } } catch (PSArgumentException mae) { ThrowError(resolvedPath, "PathNotAbsolute", mae, ErrorCategory.InvalidArgument); } catch (PSArgumentNullException mane) { ThrowError(resolvedPath, "PathNull", mane, ErrorCategory.InvalidArgument); } catch (ArgumentException ae) { ThrowError(resolvedPath, "InvalidCharactersInPath", ae, ErrorCategory.InvalidArgument); } // looks like saving succeeded. // Now try changing $console Exception e = null; try { //Update $Console variable Context.EngineSessionState.SetConsoleVariable(); } catch (ArgumentNullException ane) { e = ane; } catch (ArgumentOutOfRangeException aor) { e = aor; } catch (ArgumentException ae) { e = ae; } catch (SessionStateUnauthorizedAccessException sue) { e = sue; } catch (SessionStateOverflowException sof) { e = sof; } catch (ProviderNotFoundException pnf) { e = pnf; } catch (System.Management.Automation.DriveNotFoundException dnfe) { e = dnfe; } catch (NotSupportedException ne) { e = ne; } catch (ProviderInvocationException pin) { e = pin; } if (e != null) { throw PSTraceSource.NewInvalidOperationException(e, ConsoleInfoErrorStrings.ConsoleVariableCannotBeSet, resolvedPath); } }
Update(Int64 sourceId, ProgressRecord record) { Dbg.Assert(record != null, "record should not be null"); do { if (record.ParentActivityId == record.ActivityId) { // ignore malformed records. break; } ArrayList listWhereFound = null; int indexWhereFound = -1; ProgressNode foundNode = FindNodeById(sourceId, record.ActivityId, out listWhereFound, out indexWhereFound); if (foundNode != null) { Dbg.Assert(listWhereFound != null, "node found, but list not identified"); Dbg.Assert(indexWhereFound >= 0, "node found, but index not returned"); if (record.RecordType == ProgressRecordType.Completed) { RemoveNodeAndPromoteChildren(listWhereFound, indexWhereFound); break; } if (record.ParentActivityId == foundNode.ParentActivityId) { // record is an update to an existing activity. Copy the record data into the found node, and // reset the age of the node. foundNode.Activity = record.Activity; foundNode.StatusDescription = record.StatusDescription; foundNode.CurrentOperation = record.CurrentOperation; foundNode.PercentComplete = Math.Min(record.PercentComplete, 100); foundNode.SecondsRemaining = record.SecondsRemaining; foundNode.Age = 0; break; } else { // The record's parent Id mismatches with that of the found node's. We interpret // this to mean that the activity represented by the record (and the found node) is // being "re-parented" elsewhere. So we remove the found node and treat the record // as a new activity. RemoveNodeAndPromoteChildren(listWhereFound, indexWhereFound); } } // At this point, the record's activity is not in the tree. So we need to add it. if (record.RecordType == ProgressRecordType.Completed) { // We don't track completion records that don't correspond to activities we're not // already tracking. break; } ProgressNode newNode = new ProgressNode(sourceId, record); // If we're adding a node, and we have no more space, then we need to pick a node to evict. while (_nodeCount >= maxNodeCount) { EvictNode(); } if (newNode.ParentActivityId >= 0) { ProgressNode parentNode = FindNodeById(newNode.SourceId, newNode.ParentActivityId); if (parentNode != null) { if (parentNode.Children == null) { parentNode.Children = new ArrayList(); } AddNode(parentNode.Children, newNode); break; } // The parent node is not in the tree. Make the new node's parent the root, // and add it to the tree. If the parent ever shows up, then the next time // we receive a record for this activity, the parent id's won't match, and the // activity will be properly re-parented. newNode.ParentActivityId = -1; } AddNode(_topLevelNodes, newNode); } while (false); // At this point the tree is up-to-date. Make a pass to age all of the nodes AgeNodesAndResetStyle(); }
private void ParseHelper(string[] args) { Dbg.Assert(args != null, "Argument 'args' to ParseHelper should never be null"); bool noexitSeen = false; for (int i = 0; i < args.Length; ++i) { (string SwitchKey, bool ShouldBreak)switchKeyResults = GetSwitchKey(args, ref i, this, ref noexitSeen); if (switchKeyResults.ShouldBreak) { break; } string switchKey = switchKeyResults.SwitchKey; // If version is in the commandline, don't continue to look at any other parameters if (MatchSwitch(switchKey, "version", "v")) { _showVersion = true; _showBanner = false; _noInteractive = true; _skipUserInit = true; _noExit = false; break; } if (MatchSwitch(switchKey, "help", "h") || MatchSwitch(switchKey, "?", "?")) { _showHelp = true; _showExtendedHelp = true; _abortStartup = true; } else if (MatchSwitch(switchKey, "login", "l")) { // This handles -Login on Windows only, where it does nothing. // On *nix, -Login is handled much earlier to improve startup performance. } else if (MatchSwitch(switchKey, "noexit", "noe")) { _noExit = true; noexitSeen = true; } else if (MatchSwitch(switchKey, "noprofile", "nop")) { _skipUserInit = true; } else if (MatchSwitch(switchKey, "nologo", "nol")) { _showBanner = false; } else if (MatchSwitch(switchKey, "noninteractive", "noni")) { _noInteractive = true; } else if (MatchSwitch(switchKey, "socketservermode", "so")) { _socketServerMode = true; } else if (MatchSwitch(switchKey, "servermode", "s")) { _serverMode = true; } else if (MatchSwitch(switchKey, "namedpipeservermode", "nam")) { _namedPipeServerMode = true; } else if (MatchSwitch(switchKey, "sshservermode", "sshs")) { _sshServerMode = true; } else if (MatchSwitch(switchKey, "interactive", "i")) { _noInteractive = false; } else if (MatchSwitch(switchKey, "configurationname", "config")) { ++i; if (i >= args.Length) { WriteCommandLineError( CommandLineParameterParserStrings.MissingConfigurationNameArgument); break; } _configurationName = args[i]; } else if (MatchSwitch(switchKey, "custompipename", "cus")) { ++i; if (i >= args.Length) { WriteCommandLineError( CommandLineParameterParserStrings.MissingCustomPipeNameArgument); break; } if (!Platform.IsWindows) { int maxNameLength = (Platform.IsLinux ? MaxPipePathLengthLinux : MaxPipePathLengthMacOS) - Path.GetTempPath().Length; if (args[i].Length > maxNameLength) { WriteCommandLineError( string.Format( CommandLineParameterParserStrings.CustomPipeNameTooLong, maxNameLength, args[i], args[i].Length)); break; } } _customPipeName = args[i]; } else if (MatchSwitch(switchKey, "command", "c")) { if (!ParseCommand(args, ref i, noexitSeen, false)) { break; } } else if (MatchSwitch(switchKey, "windowstyle", "w")) { #if UNIX WriteCommandLineError( CommandLineParameterParserStrings.WindowStyleArgumentNotImplemented); break; #else ++i; if (i >= args.Length) { WriteCommandLineError( CommandLineParameterParserStrings.MissingWindowStyleArgument); break; } try { ProcessWindowStyle style = (ProcessWindowStyle)LanguagePrimitives.ConvertTo( args[i], typeof(ProcessWindowStyle), CultureInfo.InvariantCulture); ConsoleControl.SetConsoleMode(style); } catch (PSInvalidCastException e) { WriteCommandLineError( string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidWindowStyleArgument, args[i], e.Message)); break; } #endif } else if (MatchSwitch(switchKey, "file", "f")) { if (!ParseFile(args, ref i, noexitSeen)) { break; } } #if DEBUG // this option is useful when debugging ConsoleHost remotely using VS remote debugging, as you can only // attach to an already running process with that debugger. else if (MatchSwitch(switchKey, "wait", "w")) { // This does not need to be localized: its chk only ((ConsoleHostUserInterface)_hostUI).WriteToConsole("Waiting - type enter to continue:", false); _hostUI.ReadLine(); } // this option is useful for testing the initial InitialSessionState experience else if (MatchSwitch(switchKey, "iss", "iss")) { // Just toss this option, it was processed earlier... } // this option is useful for testing the initial InitialSessionState experience // this is independent of the normal wait switch because configuration processing // happens so early in the cycle... else if (MatchSwitch(switchKey, "isswait", "isswait")) { // Just toss this option, it was processed earlier... } else if (MatchSwitch(switchKey, "modules", "mod")) { if (ConsoleHost.DefaultInitialSessionState == null) { WriteCommandLineError( "The -module option can only be specified with the -iss option.", showHelp: true, showBanner: false); break; } ++i; int moduleCount = 0; // Accumulate the arguments to this script... while (i < args.Length) { string arg = args[i]; if (!string.IsNullOrEmpty(arg) && CharExtensions.IsDash(arg[0])) { break; } else { ConsoleHost.DefaultInitialSessionState.ImportPSModule(new string[] { arg }); moduleCount++; } ++i; } if (moduleCount < 1) { _hostUI.WriteErrorLine("No modules specified for -module option"); } } #endif else if (MatchSwitch(switchKey, "outputformat", "o") || MatchSwitch(switchKey, "of", "o")) { ParseFormat(args, ref i, ref _outFormat, CommandLineParameterParserStrings.MissingOutputFormatParameter); _outputFormatSpecified = true; } else if (MatchSwitch(switchKey, "inputformat", "in") || MatchSwitch(switchKey, "if", "if")) { ParseFormat(args, ref i, ref _inFormat, CommandLineParameterParserStrings.MissingInputFormatParameter); } else if (MatchSwitch(switchKey, "executionpolicy", "ex") || MatchSwitch(switchKey, "ep", "ep")) { ParseExecutionPolicy(args, ref i, ref _executionPolicy, CommandLineParameterParserStrings.MissingExecutionPolicyParameter); } else if (MatchSwitch(switchKey, "encodedcommand", "e") || MatchSwitch(switchKey, "ec", "e")) { _wasCommandEncoded = true; if (!ParseCommand(args, ref i, noexitSeen, true)) { break; } } else if (MatchSwitch(switchKey, "encodedarguments", "encodeda") || MatchSwitch(switchKey, "ea", "ea")) { if (!CollectArgs(args, ref i)) { break; } } else if (MatchSwitch(switchKey, "settingsfile", "settings")) { // Parse setting file arg and write error if (!TryParseSettingFileHelper(args, ++i, this)) { break; } } else if (MatchSwitch(switchKey, "sta", "s")) { if (!Platform.IsWindowsDesktop) { WriteCommandLineError( CommandLineParameterParserStrings.STANotImplemented); break; } if (_staMode.HasValue) { // -sta and -mta are mutually exclusive. WriteCommandLineError( CommandLineParameterParserStrings.MtaStaMutuallyExclusive); break; } _staMode = true; } else if (MatchSwitch(switchKey, "mta", "mta")) { if (!Platform.IsWindowsDesktop) { WriteCommandLineError( CommandLineParameterParserStrings.MTANotImplemented); break; } if (_staMode.HasValue) { // -sta and -mta are mutually exclusive. WriteCommandLineError( CommandLineParameterParserStrings.MtaStaMutuallyExclusive); break; } _staMode = false; } else if (MatchSwitch(switchKey, "workingdirectory", "wo") || MatchSwitch(switchKey, "wd", "wd")) { ++i; if (i >= args.Length) { WriteCommandLineError( CommandLineParameterParserStrings.MissingWorkingDirectoryArgument); break; } _workingDirectory = args[i]; } #if !UNIX else if (MatchSwitch(switchKey, "removeworkingdirectorytrailingcharacter", "removeworkingdirectorytrailingcharacter")) { _removeWorkingDirectoryTrailingCharacter = true; } #endif else { // The first parameter we fail to recognize marks the beginning of the file string. --i; if (!ParseFile(args, ref i, noexitSeen)) { break; } } } if (_showHelp) { ShowHelp(); } if (_showBanner && !_showHelp) { DisplayBanner(); if (UpdatesNotification.CanNotifyUpdates) { UpdatesNotification.ShowUpdateNotification(_hostUI); } } Dbg.Assert( ((_exitCode == ConsoleHost.ExitCodeBadCommandLineParameter) && _abortStartup) || (_exitCode == ConsoleHost.ExitCodeSuccess), "if exit code is failure, then abortstartup should be true"); }
CompressToFit(PSHostRawUserInterface rawUi, int maxHeight, int maxWidth) { Dbg.Assert(_topLevelNodes != null, "Shouldn't need to compress if no data exists"); int nodesCompressed = 0; // This algorithm potentially makes many, many passeses over the tree. It might be possible to optimize // that some, but I'm not trying to be too clever just yet. if ( CompressToFitHelper( rawUi, maxHeight, maxWidth, out nodesCompressed, ProgressNode.RenderStyle.FullPlus, ProgressNode.RenderStyle.Full)) { return(0); } if ( CompressToFitHelper( rawUi, maxHeight, maxWidth, out nodesCompressed, ProgressNode.RenderStyle.Full, ProgressNode.RenderStyle.Compact)) { return(0); } if ( CompressToFitHelper( rawUi, maxHeight, maxWidth, out nodesCompressed, ProgressNode.RenderStyle.Compact, ProgressNode.RenderStyle.Minimal)) { return(0); } if ( CompressToFitHelper( rawUi, maxHeight, maxWidth, out nodesCompressed, ProgressNode.RenderStyle.Minimal, ProgressNode.RenderStyle.Invisible)) { // The nodes that we compressed here are now invisible. return(nodesCompressed); } Dbg.Assert(false, "with all nodes invisible, we should never reach this point."); return(0); }