//
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;
namespace Microsoft.Samples.PowerShell.Host
{
///
/// Sample implementation of the PSHostUserInterface class.
/// This is more complete than the previous samples however
/// there are still members that are unimplemented by this class.
/// Members that aren't implemented usually throw a
/// NotImplementedException
/// though some just do nothing and silently return. Members
/// that map simply onto the existing .NET console APIs are
/// supported. Also a basic implementation of the prompt
/// API provided. The credential and secure string methods are
/// not supported.
///
class MyHostUserInterface : PSHostUserInterface
{
public override Dictionary Prompt(
string caption, string message,
Collection descriptions)
{
Write(ConsoleColor.Blue, ConsoleColor.Black,
caption + "\n" + message + " ");
Dictionary results =
new Dictionary();
foreach (FieldDescription fd in descriptions)
{
string[] label = GetHotkeyAndLabel(fd.Label);
WriteLine(label[1]);
string userData = Console.ReadLine();
if (userData == null)
return null;
results[fd.Name] = PSObject.AsPSObject(userData);
}
return results;
}
public override int PromptForChoice(
string caption, string message,
Collection choices, int defaultChoice)
{
// Write the caption and message strings in Blue.
WriteLine(ConsoleColor.Blue, ConsoleColor.Black,
caption + "\n" + message + "\n");
// Convert the choice collection into something that's a
// little easier to work with
// See the BuildHotkeysAndPlainLabels method for details.
Dictionary results =
new Dictionary();
string[,] promptData = BuildHotkeysAndPlainLabels(choices);
// Format the overall choice prompt string to display...
StringBuilder sb = new StringBuilder();
for (int element=0; element < choices.Count; element++)
{
sb.Append(String.Format(CultureInfo.CurrentCulture,"|{0}> {1} ",
promptData[0,element], promptData[1, element]));
}
sb.Append(String.Format(CultureInfo.CurrentCulture,"[Default is ({0}]",
promptData[0,defaultChoice]));
// loop reading prompts until a match is made, the default is
// chosen or the loop is interrupted with ctrl-C.
while (true)
{
WriteLine(ConsoleColor.Cyan, ConsoleColor.Black, sb.ToString());
string data = Console.ReadLine().Trim().ToUpper(CultureInfo.CurrentCulture);
// if the choice string was empty, use the default selection
if (data.Length == 0)
return defaultChoice;
// see if the selection matched and return the
// corresponding index if it did...
for (int i = 0; i < choices.Count; i++)
{
if (promptData[0, i] == data)
return i;
}
WriteErrorLine("Invalid choice: " + data);
}
}
///
/// Parse a string containing a hotkey character.
///
/// Take a string of the form
/// Yes to &all
/// and returns a two-dimensional array split out as
/// "A", "Yes to all".
///
/// The string to process
///
/// A two dimensional array containing the parsed components.
///
private static string[] GetHotkeyAndLabel(string input)
{
string[] result = new string[] {String.Empty, String.Empty };
string[] fragments = input.Split('&');
if (fragments.Length == 2)
{
if (fragments[1].Length > 0)
result[0] = fragments[1][0].ToString().
ToUpper(CultureInfo.CurrentCulture);
result[1] = (fragments[0] + fragments[1]).Trim();
}
else
{
result[1] = input;
}
return result;
}
///
/// This is a private worker function splits out the
/// accelerator keys from the menu and builds a two
/// dimentional array with the first access containing the
/// accelerator and the second containing the label string
/// with the & removed.
///
/// The choice collection to process
///
/// A two dimensional array containing the accelerator characters
/// and the cleaned-up labels
private static string[,] BuildHotkeysAndPlainLabels(
Collection choices)
{
// we will allocate the result array
string[,] hotkeysAndPlainLabels = new string[2, choices.Count];
for (int i = 0; i < choices.Count; ++i)
{
string[] hotkeyAndLabel = GetHotkeyAndLabel(choices[i].Label);
hotkeysAndPlainLabels[0,i] = hotkeyAndLabel[0];
hotkeysAndPlainLabels[1,i] = hotkeyAndLabel[1];
}
return hotkeysAndPlainLabels;
}
public override PSCredential PromptForCredential(
string caption, string message, string userName, string targetName)
{
throw new NotImplementedException(
"The method PromptForCredential() is not implemented by MyHost.");
}
public override PSCredential PromptForCredential(
string caption, string message, string userName,
string targetName, PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options)
{
throw new NotImplementedException(
"The method PromptForCredential() is not implemented by MyHost.");
}
private MyRawUserInterface myRawUi = new MyRawUserInterface();
public override PSHostRawUserInterface RawUI
{
get { return myRawUi; }
}
public override string ReadLine()
{
return Console.ReadLine();
}
public override System.Security.SecureString ReadLineAsSecureString()
{
throw new NotImplementedException(
"The method ReadLineAsSecureString() is not implemented by MyHost.");
}
public override void Write(string value)
{
Console.Write(value); ;
}
public override void Write(ConsoleColor foregroundColor,
ConsoleColor backgroundColor, string value)
{
ConsoleColor oldFg = Console.ForegroundColor;
ConsoleColor oldBg = Console.BackgroundColor;
Console.ForegroundColor = foregroundColor;
Console.BackgroundColor = backgroundColor;
Console.Write(value);
Console.ForegroundColor = oldFg;
Console.BackgroundColor = oldBg;
}
public override void WriteLine(ConsoleColor foregroundColor,
ConsoleColor backgroundColor, string value)
{
ConsoleColor oldFg = Console.ForegroundColor;
ConsoleColor oldBg = Console.BackgroundColor;
Console.ForegroundColor = foregroundColor;
Console.BackgroundColor = backgroundColor;
Console.WriteLine(value);
Console.ForegroundColor = oldFg;
Console.BackgroundColor = oldBg;
}
public override void WriteDebugLine(string message)
{
this.WriteLine(ConsoleColor.DarkYellow, ConsoleColor.Black,
String.Format(CultureInfo.CurrentCulture, "DEBUG: {0}", message));
}
public override void WriteErrorLine(string value)
{
this.WriteLine(ConsoleColor.Red, ConsoleColor.Black, value);
}
public override void WriteLine()
{
Console.WriteLine();
}
public override void WriteLine(string value)
{
Console.WriteLine(value);
}
public override void WriteVerboseLine(string message)
{
this.WriteLine(ConsoleColor.Green, ConsoleColor.Black,
String.Format(CultureInfo.CurrentCulture,"VERBOSE: {0}", message));
}
public override void WriteWarningLine(string message)
{
this.WriteLine(ConsoleColor.Yellow, ConsoleColor.Black,
String.Format(CultureInfo.CurrentCulture,"WARNING: {0}", message));
}
///
/// Progress is not implemented by this class. Since it's not
/// required for the cmdlet to work, it is better to do nothing
/// instead of throwing an exception.
///
/// See base class
/// See base class
public override void WriteProgress(long sourceId, ProgressRecord record)
{
; // Do nothing...
}
}
}