/// <summary> /// This method is added to be backward compatible with V1 hosts w.r.t /// new PromptForChoice method added in PowerShell V2. /// </summary> /// <param name="caption"></param> /// <param name="message"></param> /// <param name="choices"></param> /// <param name="defaultChoices"></param> /// <returns></returns> /// <exception cref="ArgumentException"> /// 1. Choices is null. /// 2. Choices.Count = 0 /// 3. DefaultChoice is either less than 0 or greater than Choices.Count /// </exception> private Collection <int> EmulatePromptForMultipleChoice(string caption, string message, Collection <ChoiceDescription> choices, IEnumerable <int> defaultChoices) { Dbg.Assert(_externalUI != null, "externalUI cannot be null."); if (choices == null) { throw PSTraceSource.NewArgumentNullException(nameof(choices)); } if (choices.Count == 0) { throw PSTraceSource.NewArgumentException(nameof(choices), InternalHostUserInterfaceStrings.EmptyChoicesError, "choices"); } Dictionary <int, bool> defaultChoiceKeys = new Dictionary <int, bool>(); if (defaultChoices != null) { foreach (int defaultChoice in defaultChoices) { if ((defaultChoice < 0) || (defaultChoice >= choices.Count)) { throw PSTraceSource.NewArgumentOutOfRangeException("defaultChoice", defaultChoice, InternalHostUserInterfaceStrings.InvalidDefaultChoiceForMultipleSelection, "defaultChoice", "choices", defaultChoice); } defaultChoiceKeys.TryAdd(defaultChoice, true); } } // Construct the caption + message + list of choices + default choices Text.StringBuilder choicesMessage = new Text.StringBuilder(); char newLine = '\n'; if (!string.IsNullOrEmpty(caption)) { choicesMessage.Append(caption); choicesMessage.Append(newLine); } if (!string.IsNullOrEmpty(message)) { choicesMessage.Append(message); choicesMessage.Append(newLine); } string[,] hotkeysAndPlainLabels = null; HostUIHelperMethods.BuildHotkeysAndPlainLabels(choices, out hotkeysAndPlainLabels); string choiceTemplate = "[{0}] {1} "; for (int i = 0; i < hotkeysAndPlainLabels.GetLength(1); ++i) { string choice = string.Format( Globalization.CultureInfo.InvariantCulture, choiceTemplate, hotkeysAndPlainLabels[0, i], hotkeysAndPlainLabels[1, i]); choicesMessage.Append(choice); choicesMessage.Append(newLine); } // default choices string defaultPrompt = string.Empty; if (defaultChoiceKeys.Count > 0) { string prepend = string.Empty; Text.StringBuilder defaultChoicesBuilder = new Text.StringBuilder(); foreach (int defaultChoice in defaultChoiceKeys.Keys) { string defaultStr = hotkeysAndPlainLabels[0, defaultChoice]; if (string.IsNullOrEmpty(defaultStr)) { defaultStr = hotkeysAndPlainLabels[1, defaultChoice]; } defaultChoicesBuilder.Append(string.Format(Globalization.CultureInfo.InvariantCulture, "{0}{1}", prepend, defaultStr)); prepend = ","; } string defaultChoicesStr = defaultChoicesBuilder.ToString(); if (defaultChoiceKeys.Count == 1) { defaultPrompt = StringUtil.Format(InternalHostUserInterfaceStrings.DefaultChoice, defaultChoicesStr); } else { defaultPrompt = StringUtil.Format(InternalHostUserInterfaceStrings.DefaultChoicesForMultipleChoices, defaultChoicesStr); } } string messageToBeDisplayed = choicesMessage.ToString() + defaultPrompt + newLine; // read choices from the user Collection <int> result = new Collection <int>(); int choicesSelected = 0; while (true) { string choiceMsg = StringUtil.Format(InternalHostUserInterfaceStrings.ChoiceMessage, choicesSelected); messageToBeDisplayed += choiceMsg; _externalUI.WriteLine(messageToBeDisplayed); string response = _externalUI.ReadLine(); // they just hit enter if (response.Length == 0) { // this may happen when // 1. user wants to go with the defaults // 2. user selected some choices and wanted those // choices to be picked. // user did not pick up any choices..choose the default if ((result.Count == 0) && (defaultChoiceKeys.Keys.Count >= 0)) { // if there's a default, pick that one. foreach (int defaultChoice in defaultChoiceKeys.Keys) { result.Add(defaultChoice); } } // allow for no choice selection. break; } int choicePicked = HostUIHelperMethods.DetermineChoicePicked(response.Trim(), choices, hotkeysAndPlainLabels); if (choicePicked >= 0) { result.Add(choicePicked); choicesSelected++; } // reset messageToBeDisplayed messageToBeDisplayed = string.Empty; } return(result); }
/// <summary> /// See base class. /// </summary> /// <param name="caption"></param> /// <param name="message"></param> /// <param name="choices"></param> /// <param name="defaultChoice"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// If <paramref name="choices"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// If <paramref name="choices"/>.Count is 0. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// If <paramref name="defaultChoice"/> is greater than /// the length of <paramref name="choices"/>. /// </exception> /// <exception cref="PromptingException"> /// when prompt is canceled by, for example, Ctrl-c. /// </exception> public override int PromptForChoice(string caption, string message, Collection <ChoiceDescription> choices, int defaultChoice) { HandleThrowOnReadAndPrompt(); if (choices == null) { throw PSTraceSource.NewArgumentNullException("choices"); } if (choices.Count == 0) { throw PSTraceSource.NewArgumentException("choices", ConsoleHostUserInterfaceStrings.EmptyChoicesErrorTemplate, "choices"); } if ((defaultChoice < -1) || (defaultChoice >= choices.Count)) { throw PSTraceSource.NewArgumentOutOfRangeException("defaultChoice", defaultChoice, ConsoleHostUserInterfaceStrings.InvalidDefaultChoiceErrorTemplate, "defaultChoice", "choice"); } // we lock here so that multiple threads won't interleave the various reads and writes here. lock (_instanceLock) { if (!string.IsNullOrEmpty(caption)) { // Should be a skin lookup WriteLineToConsole(); WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption)); WriteLineToConsole(); } if (!string.IsNullOrEmpty(message)) { WriteLineToConsole(WrapToCurrentWindowWidth(message)); } int result = defaultChoice; string[,] hotkeysAndPlainLabels = null; HostUIHelperMethods.BuildHotkeysAndPlainLabels(choices, out hotkeysAndPlainLabels); Dictionary <int, bool> defaultChoiceKeys = new Dictionary <int, bool>(); // add the default choice key only if it is valid. -1 is used to specify // no default. if (defaultChoice >= 0) { defaultChoiceKeys.Add(defaultChoice, true); } do { WriteChoicePrompt(hotkeysAndPlainLabels, defaultChoiceKeys, false); ReadLineResult rlResult; string response = ReadChoiceResponse(out rlResult); if (rlResult == ReadLineResult.endedOnBreak) { string msg = ConsoleHostUserInterfaceStrings.PromptCanceledError; PromptingException e = new PromptingException( msg, null, "PromptForChoiceCanceled", ErrorCategory.OperationStopped); throw e; } if (response.Length == 0) { // they just hit enter. if (defaultChoice >= 0) { // if there's a default, pick that one. result = defaultChoice; break; } continue; } // decide which choice they made. if (response.Trim() == "?") { // show the help ShowChoiceHelp(choices, hotkeysAndPlainLabels); continue; } result = HostUIHelperMethods.DetermineChoicePicked(response.Trim(), choices, hotkeysAndPlainLabels); if (result >= 0) { break; } // their input matched none of the choices, so prompt again }while (true); return(result); } }
private Collection <int> EmulatePromptForMultipleChoice(string caption, string message, Collection <ChoiceDescription> choices, IEnumerable <int> defaultChoices) { if (choices == null) { throw PSTraceSource.NewArgumentNullException("choices"); } if (choices.Count == 0) { throw PSTraceSource.NewArgumentException("choices", "InternalHostUserInterfaceStrings", "EmptyChoicesError", new object[] { "choices" }); } Dictionary <int, bool> dictionary = new Dictionary <int, bool>(); if (defaultChoices != null) { foreach (int num in defaultChoices) { if ((num < 0) || (num >= choices.Count)) { throw PSTraceSource.NewArgumentOutOfRangeException("defaultChoice", num, "InternalHostUserInterfaceStrings", "InvalidDefaultChoiceForMultipleSelection", new object[] { "defaultChoice", "choices", num }); } if (!dictionary.ContainsKey(num)) { dictionary.Add(num, true); } } } StringBuilder builder = new StringBuilder(); char ch = '\n'; if (!string.IsNullOrEmpty(caption)) { builder.Append(caption); builder.Append(ch); } if (!string.IsNullOrEmpty(message)) { builder.Append(message); builder.Append(ch); } string[,] hotkeysAndPlainLabels = null; HostUIHelperMethods.BuildHotkeysAndPlainLabels(choices, out hotkeysAndPlainLabels); string format = "[{0}] {1} "; for (int i = 0; i < hotkeysAndPlainLabels.GetLength(1); i++) { string str2 = string.Format(CultureInfo.InvariantCulture, format, new object[] { hotkeysAndPlainLabels[0, i], hotkeysAndPlainLabels[1, i] }); builder.Append(str2); builder.Append(ch); } string str3 = ""; if (dictionary.Count > 0) { string str4 = ""; StringBuilder builder2 = new StringBuilder(); foreach (int num3 in dictionary.Keys) { string str5 = hotkeysAndPlainLabels[0, num3]; if (string.IsNullOrEmpty(str5)) { str5 = hotkeysAndPlainLabels[1, num3]; } builder2.Append(string.Format(CultureInfo.InvariantCulture, "{0}{1}", new object[] { str4, str5 })); str4 = ","; } string str6 = builder2.ToString(); if (dictionary.Count == 1) { str3 = StringUtil.Format(InternalHostUserInterfaceStrings.DefaultChoice, str6); } else { str3 = StringUtil.Format(InternalHostUserInterfaceStrings.DefaultChoicesForMultipleChoices, str6); } } string str7 = builder.ToString() + str3 + ch; Collection <int> collection = new Collection <int>(); int o = 0; while (true) { string str8 = StringUtil.Format(InternalHostUserInterfaceStrings.ChoiceMessage, o); str7 = str7 + str8; this.externalUI.WriteLine(str7); string str9 = this.externalUI.ReadLine(); if (str9.Length == 0) { if ((collection.Count == 0) && (dictionary.Keys.Count >= 0)) { foreach (int num5 in dictionary.Keys) { collection.Add(num5); } } return(collection); } int item = HostUIHelperMethods.DetermineChoicePicked(str9.Trim(), choices, hotkeysAndPlainLabels); if (item >= 0) { collection.Add(item); o++; } str7 = ""; } }
/// <summary> /// Presents a dialog allowing the user to choose options from a set of options. /// </summary> /// <param name="caption"> /// Caption to precede or title the prompt. E.g. "Parameters for get-foo (instance 1 of 2)" /// </param> /// <param name="message"> /// A message that describes what the choice is for. /// </param> /// <param name="choices"> /// An Collection of ChoiceDescription objects that describe each choice. /// </param> /// <param name="defaultChoices"> /// The index of the labels in the choices collection element to be presented to the user as /// the default choice(s). /// </param> /// <returns> /// The indices of the choice elements that corresponds to the options selected. /// </returns> /// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForChoice"/> public Collection <int> PromptForChoice(string caption, string message, Collection <ChoiceDescription> choices, IEnumerable <int> defaultChoices) { HandleThrowOnReadAndPrompt(); if (choices == null) { throw PSTraceSource.NewArgumentNullException("choices"); } if (choices.Count == 0) { throw PSTraceSource.NewArgumentException("choices", ConsoleHostUserInterfaceStrings.EmptyChoicesErrorTemplate, "choices"); } Dictionary <int, bool> defaultChoiceKeys = new Dictionary <int, bool>(); if (defaultChoices != null) { foreach (int defaultChoice in defaultChoices) { if ((defaultChoice < 0) || (defaultChoice >= choices.Count)) { throw PSTraceSource.NewArgumentOutOfRangeException("defaultChoice", defaultChoice, ConsoleHostUserInterfaceStrings.InvalidDefaultChoiceForMultipleSelection, "defaultChoice", "choices", defaultChoice); } if (!defaultChoiceKeys.ContainsKey(defaultChoice)) { defaultChoiceKeys.Add(defaultChoice, true); } } } Collection <int> result = new Collection <int>(); // we lock here so that multiple threads won't interleave the various reads and writes here. lock (_instanceLock) { // write caption on the console, if present. if (!string.IsNullOrEmpty(caption)) { // Should be a skin lookup WriteLineToConsole(); WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption)); WriteLineToConsole(); } // write message if (!string.IsNullOrEmpty(message)) { WriteLineToConsole(WrapToCurrentWindowWidth(message)); } string[,] hotkeysAndPlainLabels = null; HostUIHelperMethods.BuildHotkeysAndPlainLabels(choices, out hotkeysAndPlainLabels); WriteChoicePrompt(hotkeysAndPlainLabels, defaultChoiceKeys, true); if (defaultChoiceKeys.Count > 0) { WriteLineToConsole(); } // used to display ChoiceMessage like Choice[0],Choice[1] etc int choicesSelected = 0; do { // write the current prompt string choiceMsg = StringUtil.Format(ConsoleHostUserInterfaceStrings.ChoiceMessage, choicesSelected); WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(choiceMsg)); ReadLineResult rlResult; string response = ReadChoiceResponse(out rlResult); if (rlResult == ReadLineResult.endedOnBreak) { string msg = ConsoleHostUserInterfaceStrings.PromptCanceledError; PromptingException e = new PromptingException( msg, null, "PromptForChoiceCanceled", ErrorCategory.OperationStopped); throw e; } // they just hit enter if (response.Length == 0) { // this may happen when // 1. user wants to go with the defaults // 2. user selected some choices and wanted those // choices to be picked. // user did not pick up any choices..choose the default if ((result.Count == 0) && (defaultChoiceKeys.Keys.Count >= 0)) { // if there's a default, pick that one. foreach (int defaultChoice in defaultChoiceKeys.Keys) { result.Add(defaultChoice); } } // allow for no choice selection. break; } // decide which choice they made. if (response.Trim() == "?") { // show the help ShowChoiceHelp(choices, hotkeysAndPlainLabels); continue; } int choicePicked = HostUIHelperMethods.DetermineChoicePicked(response.Trim(), choices, hotkeysAndPlainLabels); if (choicePicked >= 0) { result.Add(choicePicked); choicesSelected++; } // prompt for multiple choices }while (true); return(result); } }
private Collection <int> EmulatePromptForMultipleChoice( string caption, string message, Collection <ChoiceDescription> choices, IEnumerable <int> defaultChoices) { if (choices == null) { throw InternalHostUserInterface.tracer.NewArgumentNullException(nameof(choices)); } if (choices.Count == 0) { throw InternalHostUserInterface.tracer.NewArgumentException(nameof(choices), "InternalHostUserInterfaceStrings", "EmptyChoicesError", (object)nameof(choices)); } Dictionary <int, bool> dictionary = new Dictionary <int, bool>(); if (defaultChoices != null) { foreach (int defaultChoice in defaultChoices) { if (defaultChoice < 0 || defaultChoice >= choices.Count) { throw InternalHostUserInterface.tracer.NewArgumentOutOfRangeException("defaultChoice", (object)defaultChoice, "InternalHostUserInterfaceStrings", "InvalidDefaultChoiceForMultipleSelection", (object)"defaultChoice", (object)nameof(choices), (object)defaultChoice); } if (!dictionary.ContainsKey(defaultChoice)) { dictionary.Add(defaultChoice, true); } } } StringBuilder stringBuilder1 = new StringBuilder(); char ch = '\n'; if (!string.IsNullOrEmpty(caption)) { stringBuilder1.Append(caption); stringBuilder1.Append(ch); } if (!string.IsNullOrEmpty(message)) { stringBuilder1.Append(message); stringBuilder1.Append(ch); } string[,] hotkeysAndPlainLabels = (string[, ])null; HostUIHelperMethods.BuildHotkeysAndPlainLabels(choices, out hotkeysAndPlainLabels); string format = "[{0}] {1} "; for (int index = 0; index < hotkeysAndPlainLabels.GetLength(1); ++index) { string str = string.Format((IFormatProvider)CultureInfo.InvariantCulture, format, (object)hotkeysAndPlainLabels[0, index], (object)hotkeysAndPlainLabels[1, index]); stringBuilder1.Append(str); stringBuilder1.Append(ch); } string str1 = ""; if (dictionary.Count > 0) { string str2 = ""; StringBuilder stringBuilder2 = new StringBuilder(); foreach (int key in dictionary.Keys) { string str3 = hotkeysAndPlainLabels[0, key]; if (string.IsNullOrEmpty(str3)) { str3 = hotkeysAndPlainLabels[1, key]; } stringBuilder2.Append(string.Format((IFormatProvider)CultureInfo.InvariantCulture, "{0}{1}", (object)str2, (object)str3)); str2 = ","; } string str4 = stringBuilder2.ToString(); if (dictionary.Count == 1) { str1 = ResourceManagerCache.FormatResourceString("InternalHostUserInterfaceStrings", "DefaultChoice", (object)str4); } else { str1 = ResourceManagerCache.FormatResourceString("InternalHostUserInterfaceStrings", "DefaultChoicesForMultipleChoices", (object)str4); } } string str5 = stringBuilder1.ToString() + str1 + (object)ch; Collection <int> collection = new Collection <int>(); int num = 0; while (true) { string str2 = ResourceManagerCache.FormatResourceString("InternalHostUserInterfaceStrings", "ChoiceMessage", (object)num); this.externalUI.WriteLine(str5 + str2); string str3 = this.externalUI.ReadLine(); if (str3.Length != 0) { int choicePicked = HostUIHelperMethods.DetermineChoicePicked(str3.Trim(), choices, hotkeysAndPlainLabels); if (choicePicked >= 0) { collection.Add(choicePicked); ++num; } str5 = ""; } else { break; } } if (collection.Count == 0 && dictionary.Keys.Count >= 0) { foreach (int key in dictionary.Keys) { collection.Add(key); } } return(collection); }