Move DNX assemblies to src subtree

This commit is contained in:
Andrew Schwartzmeyer committed 2015-11-23 17:54:30 -08:00
1 parent 3f0fe51005
commit d6416e64e2
16 files changed

No files matched your search

@@ -0,0 +1,15 @@
(get-psprovider 'FileSystem').Home = $env:HOME
function prompt
{
"PSL " + $(get-location) + "> "
}
& {
for ($i = 0; $i -lt 26; $i++)
{
$funcname = ([System.Char]($i+65)) + ':'
$str = "function global:$funcname { set-location $funcname } "
invoke-expression $str
}
}
+217
View File
@@ -0,0 +1,217 @@
namespace Microsoft.PowerShell.Linux.Host
{
using System;
using System.Globalization;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;
/// <summary>
/// This is a sample implementation of the PSHost abstract class for
/// console applications. Not all members are implemented. Those that
/// are not implemented throw a NotImplementedException exception or
/// return nothing.
/// </summary>
internal class MyHost : PSHost, IHostSupportsInteractiveSession
{
public MyHost(Listener Listener)
{
this.Listener = Listener;
}
/// <summary>
/// A reference to the PSHost implementation.
/// </summary>
private Listener Listener;
/// <summary>
/// The culture information of the thread that created
/// this object.
/// </summary>
private CultureInfo originalCultureInfo = CultureInfo.CurrentCulture;
/// <summary>
/// The UI culture information of the thread that created
/// this object.
/// </summary>
private CultureInfo originalUICultureInfo = CultureInfo.CurrentCulture;
/// <summary>
/// The identifier of this PSHost implementation.
/// </summary>
private static Guid instanceId = Guid.NewGuid();
/// <summary>
/// A reference to the implementation of the PSHostUserInterface
/// class for this application.
/// </summary>
private MyHostUserInterface myHostUserInterface = new MyHostUserInterface();
/// <summary>
/// A reference to the runspace used to start an interactive session.
/// </summary>
public Runspace pushedRunspace = null;
/// <summary>
/// Gets the culture information to use. This implementation
/// returns a snapshot of the culture information of the thread
/// that created this object.
/// </summary>
public override CultureInfo CurrentCulture
{
get { return this.originalCultureInfo; }
}
/// <summary>
/// Gets the UI culture information to use. This implementation
/// returns a snapshot of the UI culture information of the thread
/// that created this object.
/// </summary>
public override CultureInfo CurrentUICulture
{
get { return this.originalUICultureInfo; }
}
/// <summary>
/// Gets an identifier for this host. This implementation always
/// returns the GUID allocated at instantiation time.
/// </summary>
public override Guid InstanceId
{
get { return instanceId; }
}
/// <summary>
/// Gets a string that contains the name of this host implementation.
/// Keep in mind that this string may be used by script writers to
/// identify when your host is being used.
/// </summary>
public override string Name
{
get { return "PSL"; }
}
/// <summary>
/// Gets an instance of the implementation of the PSHostUserInterface
/// class for this application. This instance is allocated once at startup time
/// and returned every time thereafter.
/// </summary>
public override PSHostUserInterface UI
{
get { return this.myHostUserInterface; }
}
/// <summary>
/// Gets the version object for this application. Typically this
/// should match the version resource in the application.
/// </summary>
public override Version Version
{
get { return new Version(1, 0, 0, 0); }
}
#region IHostSupportsInteractiveSession Properties
/// <summary>
/// Gets a value indicating whether a request
/// to open a PSSession has been made.
/// </summary>
public bool IsRunspacePushed
{
get { return this.pushedRunspace != null; }
}
/// <summary>
/// Gets or sets the runspace used by the PSSession.
/// </summary>
public Runspace Runspace
{
get { return this.Listener.myRunSpace; }
internal set { this.Listener.myRunSpace = value; }
}
#endregion IHostSupportsInteractiveSession Properties
/// <summary>
/// This API Instructs the host to interrupt the currently running
/// pipeline and start a new nested input loop. In this example this
/// functionality is not needed so the method throws a
/// NotImplementedException exception.
/// </summary>
public override void EnterNestedPrompt()
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// This API instructs the host to exit the currently running input loop.
/// In this example this functionality is not needed so the method
/// throws a NotImplementedException exception.
/// </summary>
public override void ExitNestedPrompt()
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// This API is called before an external application process is
/// started. Typically it is used to save state so that the parent
/// can restore state that has been modified by a child process (after
/// the child exits). In this example this functionality is not
/// needed so the method returns nothing.
/// </summary>
public override void NotifyBeginApplication()
{
return;
}
/// <summary>
/// This API is called after an external application process finishes.
/// Typically it is used to restore state that a child process has
/// altered. In this example, this functionality is not needed so
/// the method returns nothing.
/// </summary>
public override void NotifyEndApplication()
{
return;
}
/// <summary>
/// Indicate to the host application that exit has
/// been requested. Pass the exit code that the host
/// application should use when exiting the process.
/// </summary>
/// <param name="exitCode">The exit code that the
/// host application should use.</param>
public override void SetShouldExit(int exitCode)
{
this.Listener.ShouldExit = true;
this.Listener.ExitCode = exitCode;
}
#region IHostSupportsInteractiveSession Methods
/// <summary>
/// Requests to close a PSSession.
/// </summary>
public void PopRunspace()
{
Runspace = this.pushedRunspace;
this.pushedRunspace = null;
}
/// <summary>
/// Requests to open a PSSession.
/// </summary>
/// <param name="runspace">Runspace to use.</param>
public void PushRunspace(Runspace runspace)
{
this.pushedRunspace = Runspace;
Runspace = runspace;
}
#endregion IHostSupportsInteractiveSession Methods
}
}
@@ -0,0 +1,17 @@
# This is the makefile for all kinds of powershell hosts
#
# Currently there is powershell-run.exe, which is a very generic interactive and
# non-interactive host
POWERSHELL_RUN_FOLDER=$(MONAD)/src/host
POWERSHELL_RUN_SRCS=$(addprefix $(POWERSHELL_RUN_FOLDER)/, main.cs host.cs ui.cs rawui.cs readline.cs powershell.assembly-info.cs)
# direct dependencies to be linked in
POWERSHELL_RUN_DEPS=$(addprefix $(PSLIB)/, System.Management.Automation.dll Microsoft.PowerShell.Commands.Management.dll $(ASSEMBLY_LOAD_CONTEXT_TARGET))
POWERSHELL_RUN_REFS=$(addprefix -r:, $(POWERSHELL_RUN_DEPS))
$(PSLIB)/PSL_profile.ps1:
cp -f $(POWERSHELL_RUN_FOLDER)/$(notdir $@) $@
$(PSLIB)/powershell.exe: $(POWERSHELL_RUN_SRCS) $(POWERSHELL_RUN_DEPS) $(PSLIB)/PSL_profile.ps1
$(CSC) -out:$@ -noconfig -nostdlib -target:exe $(POWERSHELL_RUN_REFS) $(COREREF) $(POWERSHELL_RUN_SRCS)
+468
View File
@@ -0,0 +1,468 @@
namespace Microsoft.PowerShell.Linux.Host
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using PowerShell = System.Management.Automation.PowerShell;
public static class Program
{
/// <summary>
/// Creates and initiates the listener instance.
/// </summary>
public static void Main(string[] args)
{
// create the typecatalog so they can find assemblies for a given type.
TypeCatalog.GenerateTypeCatalog();
if (System.Management.Automation.ClrHost.TypeCatalog == null)
{
Console.WriteLine("TypeCatalog generation failed!");
}
bool runspaceTest = false;
// Custom argument parsing
string initialScript = null;
if (args.Length > 0)
{
for (int i = 0; i < args.Length; ++i)
{
string arg = args[i];
bool hasNext = (i+1) < args.Length;
string nextArg = hasNext ? args[i+1] : string.Empty;
// lone argument is a script
if (!hasNext && arg.EndsWith(".ps1"))
{
initialScript = Path.GetFullPath(arg);
}
// lone argument is an inline script
else if (!hasNext)
{
initialScript = arg;
}
// --runspace was specified for a simple runspace test
else if (arg == "--runspace")
{
runspaceTest = true;
}
// --file <filePath> was specified
else if (hasNext && (arg == "--file" || arg == "-f"))
{
initialScript = Path.GetFullPath(nextArg);
++i;
}
// --command <string> was specified
else if (hasNext && (arg == "--command" || arg == "-c"))
{
if (nextArg == "-")
{
initialScript = "\"TODO: read stdin using Console.OpenStandardInput\"";
}
else
{
initialScript = nextArg;
}
++i;
}
// --working-dir (not on PowerShell for Windows, may be removed)
else if (hasNext && arg == "--working-dir")
{
Directory.SetCurrentDirectory(nextArg);
++i;
}
}
}
if (runspaceTest)
{
using (var runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
using (var ps = runspace.CreatePipeline(initialScript))
{
foreach (var result in ps.Invoke())
{
Console.WriteLine(result);
}
}
runspace.Close();
}
return;
}
// TODO: check for input on stdin
// Create the listener and run it
Listener listener = new Listener(initialScript);
// only run if there was no script file passed in
if (initialScript == null)
{
// Display the welcome message.
Console.WriteLine();
Console.WriteLine("PowerShell for Linux interactive console");
Console.WriteLine("========================================");
Console.WriteLine();
Console.WriteLine("Current status:");
Console.WriteLine("- Type 'exit' to exit");
Console.WriteLine("- Utility and Management cmdlet modules are loadable");
Console.WriteLine();
listener.Run();
}
}
}
internal class Listener
{
/// <summary>
/// Used to read user input.
/// </summary>
internal ConsoleReadLine consoleReadLine = new ConsoleReadLine();
/// <summary>
/// Holds a reference to the runspace for this interpeter.
/// </summary>
internal Runspace myRunSpace;
/// <summary>
/// Indicator to tell the host application that it should exit.
/// </summary>
private bool shouldExit;
/// <summary>
/// The exit code that the host application will use to exit.
/// </summary>
private int exitCode;
/// <summary>
/// Holds a reference to the PSHost implementation for this interpreter.
/// </summary>
private MyHost myHost;
/// <summary>
/// Holds a reference to the currently executing pipeline so that it can be
/// stopped by the control-C handler.
/// </summary>
private PowerShell currentPowerShell;
/// <summary>
/// Used to serialize access to instance data.
/// </summary>
private object instanceLock = new object();
/// <summary>
/// Gets or sets a value indicating whether the host application
/// should exit.
/// </summary>
public bool ShouldExit
{
get { return this.shouldExit; }
set { this.shouldExit = value; }
}
/// <summary>
/// Gets or sets a value indicating whether the host application
/// should exit.
/// </summary>
public int ExitCode
{
get { return this.exitCode; }
set { this.exitCode = value; }
}
public Listener(string initialScript)
{
// Create the host and runspace instances for this interpreter.
// Note that this application does not support console files so
// only the default snap-ins will be available.
this.myHost = new MyHost(this);
Console.WriteLine("myHost");
InitialSessionState iss = InitialSessionState.CreateDefault2();
Console.WriteLine("iss");
this.myRunSpace = RunspaceFactory.CreateRunspace(this.myHost, iss);
Console.WriteLine("runspace created");
this.myRunSpace.Open();
Console.WriteLine("runspace opened");
// Create a PowerShell object to run the commands used to create
// $profile and load the profiles.
lock (this.instanceLock)
{
this.currentPowerShell = PowerShell.Create();
}
try
{
this.currentPowerShell.Runspace = this.myRunSpace;
PSCommand[] profileCommands = HostUtilities.GetProfileCommands("PSL");
foreach (PSCommand command in profileCommands)
{
this.currentPowerShell.Commands = command;
this.currentPowerShell.Invoke();
}
}
finally
{
// Dispose the PowerShell object and set currentPowerShell
// to null. It is locked because currentPowerShell may be
// accessed by the ctrl-C handler.
lock (this.instanceLock)
{
this.currentPowerShell.Dispose();
this.currentPowerShell = null;
}
}
// run the initial script
if (initialScript != null)
{
executeHelper(initialScript, null);
}
}
/// Sets the prompt equal to the output of the prompt function
public string Prompt(Runspace rs)
{
string returnVal = string.Empty;
if (this.myHost.IsRunspacePushed)
{
returnVal = string.Format("\n[{0}] PSL> ", this.myRunSpace.ConnectionInfo.ComputerName);
return returnVal;
}
// TODO: if we are in block mode, sep the prompt to ">> "
Pipeline pipeline = rs.CreatePipeline();
Command promptCommand = new Command("prompt");
pipeline.Commands.Add(promptCommand);
Collection<PSObject> output = pipeline.Invoke();
foreach (PSObject item in output)
{
returnVal = item.BaseObject.ToString();
}
return returnVal;
}
/// <summary>
/// A helper class that builds and executes a pipeline that writes
/// to the default output path. Any exceptions that are thrown are
/// just passed to the caller. Since all output goes to the default
/// outter, this method does not return anything.
/// </summary>
/// <param name="cmd">The script to run.</param>
/// <param name="input">Any input arguments to pass to the script.
/// If null then nothing is passed in.</param>
private void executeHelper(string cmd, object input)
{
// Ignore empty command lines.
if (string.IsNullOrEmpty(cmd))
{
return;
}
// Create the pipeline object and make it available to the
// ctrl-C handle through the currentPowerShell instance
// variable.
lock (this.instanceLock)
{
this.currentPowerShell = PowerShell.Create();
}
// Add a script and command to the pipeline and then run the pipeline. Place
// the results in the currentPowerShell variable so that the pipeline can be
// stopped.
try
{
this.currentPowerShell.Runspace = this.myRunSpace;
this.currentPowerShell.AddScript(cmd);
// Add the default outputter to the end of the pipe and then call the
// MergeMyResults method to merge the output and error streams from the
// pipeline. This will result in the output being written using the PSHost
// and PSHostUserInterface classes instead of returning objects to the host
// application.
this.currentPowerShell.AddCommand("out-default");
this.currentPowerShell.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
// If there is any input pass it in, otherwise just invoke the
// the pipeline.
PSInvocationSettings settings = new PSInvocationSettings();
settings.AddToHistory = true;
if (input != null)
{
this.currentPowerShell.Invoke(new object[] { input }, settings);
}
else
{
this.currentPowerShell.Invoke(null, settings);
}
}
finally
{
// Dispose the PowerShell object and set currentPowerShell to null.
// It is locked because currentPowerShell may be accessed by the
// ctrl-C handler.
lock (this.instanceLock)
{
this.currentPowerShell.Dispose();
this.currentPowerShell = null;
}
}
}
/// <summary>
/// To display an exception using the display formatter,
/// run a second pipeline passing in the error record.
/// The runtime will bind this to the $input variable,
/// which is why $input is being piped to the Out-String
/// cmdlet. The WriteErrorLine method is called to make sure
/// the error gets displayed in the correct error color.
/// </summary>
/// <param name="e">The exception to display.</param>
private void ReportException(Exception e)
{
if (e != null)
{
object error;
IContainsErrorRecord icer = e as IContainsErrorRecord;
if (icer != null)
{
error = icer.ErrorRecord;
}
else
{
error = (object)new ErrorRecord(e, "Host.ReportException", ErrorCategory.NotSpecified, null);
}
lock (this.instanceLock)
{
this.currentPowerShell = PowerShell.Create();
}
this.currentPowerShell.Runspace = this.myRunSpace;
try
{
this.currentPowerShell.AddScript("$input").AddCommand("out-string");
// Do not merge errors, this function will swallow errors.
Collection<PSObject> result;
PSDataCollection<object> inputCollection = new PSDataCollection<object>();
inputCollection.Add(error);
inputCollection.Complete();
result = this.currentPowerShell.Invoke(inputCollection);
if (result.Count > 0)
{
string str = result[0].BaseObject as string;
if (!string.IsNullOrEmpty(str))
{
// Remove \r\n, which is added by the Out-String cmdlet.
this.myHost.UI.WriteErrorLine(str.Substring(0, str.Length - 2));
}
}
}
finally
{
// Dispose of the pipeline and set it to null, locking it because
// currentPowerShell may be accessed by the ctrl-C handler.
lock (this.instanceLock)
{
this.currentPowerShell.Dispose();
this.currentPowerShell = null;
}
}
}
}
/// <summary>
/// Basic script execution routine. Any runtime exceptions are
/// caught and passed back to the Windows PowerShell engine to
/// display.
/// </summary>
/// <param name="cmd">Script to run.</param>
private void Execute(string cmd)
{
try
{
// Run the command with no input.
this.executeHelper(cmd, null);
}
catch (RuntimeException rte)
{
this.ReportException(rte);
}
}
/// <summary>
/// Method used to handle control-C's from the user. It calls the
/// pipeline Stop() method to stop execution. If any exceptions occur
/// they are printed to the console but otherwise ignored.
/// </summary>
/// <param name="sender">See sender property documentation of
/// ConsoleCancelEventHandler.</param>
/// <param name="e">See e property documentation of
/// ConsoleCancelEventHandler.</param>
private void HandleControlC(object sender, ConsoleCancelEventArgs e)
{
try
{
lock (this.instanceLock)
{
if (this.currentPowerShell != null && this.currentPowerShell.InvocationStateInfo.State == PSInvocationState.Running)
{
this.currentPowerShell.Stop();
}
}
e.Cancel = true;
}
catch (Exception exception)
{
this.myHost.UI.WriteErrorLine(exception.ToString());
}
}
/// <summary>
/// Implements the basic listener loop. It sets up the ctrl-C handler, then
/// reads a command from the user, executes it and repeats until the ShouldExit
/// flag is set.
/// </summary>
public void Run()
{
// Set up the control-C handler.
Console.CancelKeyPress += new ConsoleCancelEventHandler(this.HandleControlC);
//Console.TreatControlCAsInput = false;
// Read commands and run them until the ShouldExit flag is set by
// the user calling "exit".
while (!this.ShouldExit && this.myHost.Runspace != null)
{
string prompt = Prompt(this.myHost.Runspace);
this.myHost.UI.Write(ConsoleColor.White, ConsoleColor.Black, prompt);
string cmd = this.myHost.UI.ReadLine();
this.Execute(cmd);
}
// Exit with the desired exit code that was set by the exit command.
// The exit code is set in the host by the MyHost.SetShouldExit() method.
//Environment.Exit(this.ExitCode);
}
}
}
@@ -0,0 +1,4 @@
using System.Runtime.CompilerServices;
using System.Reflection;
[assembly:AssemblyFileVersionAttribute("1.0.0.0")]
[assembly:AssemblyVersion("1.0.0.0")]
@@ -0,0 +1,35 @@
{
"version": "1.0.0.0",
"description": "PowerShell On Linux Console",
"authors": [ "andschwa" ],
"tags": [ "" ],
"projectUrl": "",
"licenseUrl": "",
"dependencies": {
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-*",
"System.Management.Automation": "",
"Microsoft.PowerShell.Security": "",
"Microsoft.PowerShell.Commands.Utility": "",
"Microsoft.PowerShell.Commands.Management": ""
},
"commands": {
"powershell": "Microsoft.PowerShell.Linux.Host"
},
"frameworks": {
"dnxcore50": {
"dependencies": {
"Microsoft.CSharp": "4.0.1-*",
"System.Collections": "4.0.11-*",
"System.Console": "4.0.0-*",
"System.Diagnostics.FileVersionInfo": "4.0.0-*",
"System.Linq": "4.0.1-*",
"System.Reflection": "4.1.0-*",
"System.Runtime": "4.0.21-*",
"System.Threading": "4.0.11-*"
}
}
}
}
@@ -0,0 +1,240 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Management.Automation.Host;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Microsoft.PowerShell.Linux.Host
{
// this is all from https://msdn.microsoft.com/en-us/library/ee706570%28v=vs.85%29.aspx
internal class MyRawUserInterface : PSHostRawUserInterface
{
// this class provides features otherwise not available through .net
internal class Native
{
[DllImport("libpsnative")]
internal static extern int GetTerminalWidth();
[DllImport("libpsnative")]
internal static extern int GetTerminalHeight();
}
/// <summary>
/// Gets or sets the background color of the displayed text.
/// This maps to the corresponding Console.Background property.
/// </summary>
public override ConsoleColor BackgroundColor
{
get { return Console.BackgroundColor; }
set { Console.BackgroundColor = value; }
}
/// <summary>
/// Gets or sets the size of the host buffer. In this example the
/// buffer size is adapted from the Console buffer size members.
/// </summary>
public override Size BufferSize
{
get { return new Size(Native.GetTerminalWidth()-1,Native.GetTerminalHeight()-1); }
set { }
//get { return new Size(Console.BufferWidth, Console.BufferHeight); }
//set { Console.SetBufferSize(value.Width, value.Height); }
}
/// <summary>
/// Gets or sets the cursor position. In this example this
/// functionality is not needed so the property throws a
/// NotImplementException exception.
/// </summary>
public override Coordinates CursorPosition
{
get { throw new NotImplementedException(
"The method or operation is not implemented."); }
set { throw new NotImplementedException(
"The method or operation is not implemented."); }
}
/// <summary>
/// Gets or sets the size of the displayed cursor. In this example
/// the cursor size is taken directly from the Console.CursorSize
/// property.
/// </summary>
public override int CursorSize
{
get { return 12; }
set { }
//get { return Console.CursorSize; }
//set { Console.CursorSize = value; }
}
/// <summary>
/// Gets or sets the foreground color of the displayed text.
/// This maps to the corresponding Console.ForgroundColor property.
/// </summary>
public override ConsoleColor ForegroundColor
{
get { return Console.ForegroundColor; }
set { Console.ForegroundColor = value; }
}
/// <summary>
/// Gets a value indicating whether the user has pressed a key. This maps
/// to the corresponding Console.KeyAvailable property.
/// </summary>
public override bool KeyAvailable
{
get { return false; }
// get { return Console.KeyAvailable; }
}
/// <summary>
/// Gets the dimensions of the largest window that could be
/// rendered in the current display, if the buffer was at the least
/// that large. This example uses the Console.LargestWindowWidth and
/// Console.LargestWindowHeight properties to determine the returned
/// value of this property.
/// </summary>
public override Size MaxPhysicalWindowSize
{
// get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); }
get { return new Size(1024,768); }
}
/// <summary>
/// Gets the dimentions of the largest window size that can be
/// displayed. This example uses the Console.LargestWindowWidth and
/// console.LargestWindowHeight properties to determine the returned
/// value of this property.
/// </summary>
public override Size MaxWindowSize
{
// get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); }
get { return new Size(1024,768); }
}
/// <summary>
/// Gets or sets the position of the displayed window. This example
/// uses the Console window position APIs to determine the returned
/// value of this property.
/// </summary>
public override Coordinates WindowPosition
{
// get { return new Coordinates(Console.WindowLeft, Console.WindowTop); }
// set { Console.SetWindowPosition(value.X, value.Y); }
get { return new Coordinates(0,0); }
set { }
}
/// <summary>
/// Gets or sets the size of the displayed window. This example
/// uses the corresponding Console window size APIs to determine the
/// returned value of this property.
/// </summary>
public override Size WindowSize
{
// get { return new Size(Console.WindowWidth, Console.WindowHeight); }
// set { Console.SetWindowSize(value.Width, value.Height); }
get { return new Size(1024,768); }
set { }
}
/// <summary>
/// Gets or sets the title of the displayed window. The example
/// maps the Console.Title property to the value of this property.
/// </summary>
public override string WindowTitle
{
// get { return Console.Title; }
// set { Console.Title = value; }
get { return "window title"; }
set { }
}
/// <summary>
/// This API resets the input buffer. In this example this
/// functionality is not needed so the method returns nothing.
/// </summary>
public override void FlushInputBuffer()
{
}
/// <summary>
/// This API returns a rectangular region of the screen buffer. In
/// this example this functionality is not needed so the method throws
/// a NotImplementException exception.
/// </summary>
/// <param name="rectangle">Defines the size of the rectangle.</param>
/// <returns>Throws a NotImplementedException exception.</returns>
public override BufferCell[,] GetBufferContents(Rectangle rectangle)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// This API reads a pressed, released, or pressed and released keystroke
/// from the keyboard device, blocking processing until a keystroke is
/// typed that matches the specified keystroke options. In this example
/// this functionality is not needed so the method throws a
/// NotImplementException exception.
/// </summary>
/// <param name="options">Options, such as IncludeKeyDown, used when
/// reading the keyboard.</param>
/// <returns>Throws a NotImplementedException exception.</returns>
public override KeyInfo ReadKey(ReadKeyOptions options)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// This API crops a region of the screen buffer. In this example
/// this functionality is not needed so the method throws a
/// NotImplementException exception.
/// </summary>
/// <param name="source">The region of the screen to be scrolled.</param>
/// <param name="destination">The region of the screen to receive the
/// source region contents.</param>
/// <param name="clip">The region of the screen to include in the operation.</param>
/// <param name="fill">The character and attributes to be used to fill all cell.</param>
public override void ScrollBufferContents(Rectangle source, Coordinates destination, Rectangle clip, BufferCell fill)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// This method copies an array of buffer cells into the screen buffer
/// at a specified location. In this example this functionality is
/// not needed so the method throws a NotImplementedException exception.
/// </summary>
/// <param name="origin">The parameter is not used.</param>
/// <param name="contents">The parameter is not used.</param>
public override void SetBufferContents(Coordinates origin,
BufferCell[,] contents)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// This method copies a given character, foreground color, and background
/// color to a region of the screen buffer. In this example this
/// functionality is not needed so the method throws a
/// NotImplementException exception./// </summary>
/// <param name="rectangle">Defines the area to be filled. </param>
/// <param name="fill">Defines the fill character.</param>
public override void SetBufferContents(Rectangle rectangle, BufferCell fill)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
}
}
@@ -0,0 +1,485 @@
namespace Microsoft.PowerShell.Linux.Host
{
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Text;
/// <summary>
/// This class is used to read the command line and color the text as
/// it is entered. Tokens are determined using the PSParser.Tokenize
/// method.
/// </summary>
internal class ConsoleReadLine
{
/// <summary>
/// The buffer used to edit.
/// </summary>
private StringBuilder buffer = new StringBuilder();
/// <summary>
/// The position of the cursor within the buffer.
/// </summary>
private int current;
/// <summary>
/// The count of characters in buffer rendered.
/// </summary>
private int rendered;
/// <summary>
/// Store the anchor and handle cursor movement
/// </summary>
//private Cursor cursor;
/// <summary>
/// The array of colors for tokens, indexed by PSTokenType
/// </summary>
private ConsoleColor[] tokenColors;
/// <summary>
/// We do not pick different colors for every token, those tokens
/// use this default.
/// </summary>
private ConsoleColor defaultColor = ConsoleColor.White;
/// <summary>
/// Initializes a new instance of the ConsoleReadLine class.
/// </summary>
public ConsoleReadLine()
{
this.tokenColors = new ConsoleColor[]
{
this.defaultColor, // Unknown
ConsoleColor.Yellow, // Command
ConsoleColor.Green, // CommandParameter
ConsoleColor.Cyan, // CommandArgument
ConsoleColor.Cyan, // Number
ConsoleColor.Cyan, // String
ConsoleColor.Green, // Variable
this.defaultColor, // Member
this.defaultColor, // LoopLabel
ConsoleColor.DarkYellow, // Attribute
ConsoleColor.DarkYellow, // Type
ConsoleColor.DarkCyan, // Operator
this.defaultColor, // GroupStart
this.defaultColor, // GroupEnd
ConsoleColor.Magenta, // Keyword
ConsoleColor.Red, // Comment
ConsoleColor.DarkCyan, // StatementSeparator
this.defaultColor, // NewLine
this.defaultColor, // LineContinuation
this.defaultColor, // Position
};
}
/// <summary>
/// Read a line of text, colorizing while typing.
/// </summary>
/// <returns>The command line read</returns>
public string Read()
{
this.Initialize();
while (true)
{
// no support for Console.ReadKey in CoreCLR yet
int key = Console.Read();
char keyChar = Convert.ToChar(key);
this.Insert(keyChar);
/*
ConsoleKeyInfo key = Console.ReadKey(true);
switch (key.Key)
{
case ConsoleKey.Backspace:
this.OnBackspace();
break;
case ConsoleKey.Delete:
this.OnDelete();
break;
case ConsoleKey.Enter:
return this.OnEnter();
case ConsoleKey.RightArrow:
this.OnRight(key.Modifiers);
break;
case ConsoleKey.LeftArrow:
this.OnLeft(key.Modifiers);
break;
case ConsoleKey.Escape:
this.OnEscape();
break;
case ConsoleKey.Home:
this.OnHome();
break;
case ConsoleKey.End:
this.OnEnd();
break;
case ConsoleKey.UpArrow:
case ConsoleKey.DownArrow:
case ConsoleKey.LeftWindows:
case ConsoleKey.RightWindows:
// ignore these
continue;
default:
if (key.KeyChar == '\x0D')
{
goto case ConsoleKey.Enter; // Ctrl-M
}
if (key.KeyChar == '\x08')
{
goto case ConsoleKey.Backspace; // Ctrl-H
}
this.Insert(key);
break;
}*/
}
}
/// <summary>
/// Initializes the buffer.
/// </summary>
private void Initialize()
{
this.buffer.Length = 0;
this.current = 0;
this.rendered = 0;
//this.cursor = new Cursor();
}
/// <summary>
/// Inserts a key.
/// </summary>
/// <param name="key">The key to insert.</param>
private void Insert(char key)
{
this.buffer.Insert(this.current, key);
this.current++;
if (key == '\n')
this.Render();
}
/*
/// <summary>
/// The End key was enetered..
/// </summary>
private void OnEnd()
{
this.current = this.buffer.Length;
this.cursor.Place(this.rendered);
}
/// <summary>
/// The Home key was eneterd.
/// </summary>
private void OnHome()
{
this.current = 0;
this.cursor.Reset();
}
/// <summary>
/// The Escape key was enetered.
/// </summary>
private void OnEscape()
{
this.buffer.Length = 0;
this.current = 0;
this.Render();
}
/// <summary>
/// Moves to the left of the cursor position.
/// </summary>
/// <param name="consoleModifiers">Enumeration for Alt, Control,
/// and Shift keys.</param>
private void OnLeft(ConsoleModifiers consoleModifiers)
{
if ((consoleModifiers & ConsoleModifiers.Control) != 0)
{
// Move back to the start of the previous word.
if (this.buffer.Length > 0 && this.current != 0)
{
bool nonLetter = IsSeperator(this.buffer[this.current - 1]);
while (this.current > 0 && (this.current - 1 < this.buffer.Length))
{
this.MoveLeft();
if (IsSeperator(this.buffer[this.current]) != nonLetter)
{
if (!nonLetter)
{
this.MoveRight();
break;
}
nonLetter = false;
}
}
}
}
else
{
this.MoveLeft();
}
}
*/
/// <summary>
/// Determines if a character is a seperator.
/// </summary>
/// <param name="ch">Character to investigate.</param>
/// <returns>A value that indicates whether the character
/// is a seperator.</returns>
private static bool IsSeperator(char ch)
{
return !Char.IsLetter(ch);
}
/*
/// <summary>
/// Moves to what is to the right of the cursor position.
/// </summary>
/// <param name="consoleModifiers">Enumeration for Alt, Control,
/// and Shift keys.</param>
private void OnRight(ConsoleModifiers consoleModifiers)
{
if ((consoleModifiers & ConsoleModifiers.Control) != 0)
{
// Move to the next word.
if (this.buffer.Length != 0 && this.current < this.buffer.Length)
{
bool nonLetter = IsSeperator(this.buffer[this.current]);
while (this.current < this.buffer.Length)
{
this.MoveRight();
if (this.current == this.buffer.Length)
{
break;
}
if (IsSeperator(this.buffer[this.current]) != nonLetter)
{
if (nonLetter)
{
break;
}
nonLetter = true;
}
}
}
}
else
{
this.MoveRight();
}
}
/// <summary>
/// Moves the cursor one character to the right.
/// </summary>
private void MoveRight()
{
if (this.current < this.buffer.Length)
{
char c = this.buffer[this.current];
this.current++;
Cursor.Move(1);
}
}
/// <summary>
/// Moves the cursor one character to the left.
/// </summary>
private void MoveLeft()
{
if (this.current > 0 && (this.current - 1 < this.buffer.Length))
{
this.current--;
char c = this.buffer[this.current];
Cursor.Move(-1);
}
}
/// <summary>
/// The Enter key was entered.
/// </summary>
/// <returns>A newline character.</returns>
private string OnEnter()
{
Console.Out.Write("\n");
return this.buffer.ToString();
}
/// <summary>
/// The delete key was entered.
/// </summary>
private void OnDelete()
{
if (this.buffer.Length > 0 && this.current < this.buffer.Length)
{
this.buffer.Remove(this.current, 1);
this.Render();
}
}
/// <summary>
/// The Backspace key was entered.
/// </summary>
private void OnBackspace()
{
if (this.buffer.Length > 0 && this.current > 0)
{
this.buffer.Remove(this.current - 1, 1);
this.current--;
this.Render();
}
}
*/
/// <summary>
/// Displays the line.
/// </summary>
private void Render()
{
string text = this.buffer.ToString();
// The PowerShell tokenizer is used to decide how to colorize
// the input. Any errors in the input are returned in 'errors',
// but we won't be looking at those here.
Collection<PSParseError> errors = null;
Collection<PSToken> tokens = PSParser.Tokenize(text, out errors);
if (tokens.Count > 0)
{
// We can skip rendering tokens that end before the cursor.
int i;
for (i = 0; i < tokens.Count; ++i)
{
if (this.current >= tokens[i].Start)
{
break;
}
}
// Place the cursor at the start of the first token to render. The
// last edit may require changes to the colorization of characters
// preceding the cursor.
//this.cursor.Place(tokens[i].Start);
for (; i < tokens.Count; ++i)
{
// Write out the token. We don't use tokens[i].Content, instead we
// use the actual text from our input because the content sometimes
// excludes part of the token, e.g. the quote characters of a string.
Console.ForegroundColor = this.tokenColors[(int)tokens[i].Type];
Console.Out.Write(text.Substring(tokens[i].Start, tokens[i].Length));
// Whitespace doesn't show up in the array of tokens. Write it out here.
if (i != (tokens.Count - 1))
{
Console.ForegroundColor = this.defaultColor;
for (int j = (tokens[i].Start + tokens[i].Length); j < tokens[i + 1].Start; ++j)
{
Console.Out.Write(text[j]);
}
}
}
// It's possible there is text left over to output. This happens when there is
// some error during tokenization, e.g. a string literal is missing a closing quote.
Console.ForegroundColor = this.defaultColor;
for (int j = tokens[i - 1].Start + tokens[i - 1].Length; j < text.Length; ++j)
{
Console.Out.Write(text[j]);
}
}
else
{
// If tokenization completely failed, just redraw the whole line. This
// happens most frequently when the first token is incomplete, like a string
// literal missing a closing quote.
//this.cursor.Reset();
Console.Out.Write(text);
}
// If characters were deleted, we must write over previously written characters
if (text.Length < this.rendered)
{
Console.Out.Write(new string(' ', this.rendered - text.Length));
}
this.rendered = text.Length;
//this.cursor.Place(this.current);
}
/*
/// <summary>
/// A helper class for maintaining the cursor while editing the command line.
/// </summary>
internal class Cursor
{
/// <summary>
/// The top anchor for reposition the cursor.
/// </summary>
private int anchorTop;
/// <summary>
/// The left anchor for repositioning the cursor.
/// </summary>
private int anchorLeft;
/// <summary>
/// Initializes a new instance of the Cursor class.
/// </summary>
public Cursor()
{
this.anchorTop = Console.CursorTop;
this.anchorLeft = Console.CursorLeft;
}
/// <summary>
/// Moves the cursor.
/// </summary>
/// <param name="delta">The number of characters to move.</param>
internal static void Move(int delta)
{
int position = Console.CursorTop * Console.BufferWidth + Console.CursorLeft + delta;
Console.CursorLeft = position % Console.BufferWidth;
Console.CursorTop = position / Console.BufferWidth;
}
/// <summary>
/// Resets the cursor position.
/// </summary>
internal void Reset()
{
Console.CursorTop = this.anchorTop;
Console.CursorLeft = this.anchorLeft;
}
/// <summary>
/// Moves the cursor to a specific position.
/// </summary>
/// <param name="position">The new position.</param>
internal void Place(int position)
{
Console.CursorLeft = (this.anchorLeft + position) % Console.BufferWidth;
int cursorTop = this.anchorTop + (this.anchorLeft + position) / Console.BufferWidth;
if (cursorTop >= Console.BufferHeight)
{
this.anchorTop -= cursorTop - Console.BufferHeight + 1;
cursorTop = Console.BufferHeight - 1;
}
Console.CursorTop = cursorTop;
}
} // End Cursor
*/
}
}
@@ -0,0 +1,109 @@
namespace Microsoft.PowerShell.Linux.Host
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Reflection;
using Microsoft.Extensions.PlatformAbstractions;
using System.Management.Automation.Runspaces;
internal class TypeCatalog
{
internal static void GenerateTypeCatalog() {
TrackPackage("System.Management.Automation");
TrackPackage("Microsoft.PowerShell.Commands.Management");
TrackPackage("Microsoft.PowerShell.Commands.Utility");
TrackPackage("Microsoft.PowerShell.Security");
TrackAssembly(typeof(System.String).GetTypeInfo().Assembly);
System.Management.Automation.ClrHost.TypeCatalog = types;
TrackAssembly(typeof (System.Diagnostics.FileVersionInfo).GetTypeInfo().Assembly);
TrackType("CmdletBindingAttribute",typeof(CmdletBindingAttribute));
TrackType("ParameterAttribute", typeof(ParameterAttribute));
TrackType("string", typeof(string));
TrackType("int", typeof(int));
TrackType("Hashtable", typeof(Hashtable));
TrackType("ValidateSetAttribute", typeof(ValidateSetAttribute));
TrackType("switch", typeof(SwitchParameter));
TrackType("OutputTypeAttribute", typeof(OutputTypeAttribute));
TrackType("AllowNullAttribute", typeof(AllowNullAttribute));
TrackType("AllowEmptyStringAttribute", typeof(AllowEmptyStringAttribute));
TrackType("PSObject", typeof(PSObject));
TrackType("ValidateRangeAttribute", typeof(ValidateRangeAttribute));
}
private static void TrackPackage(string packageName)
{
if (!packages.Contains(packageName))
{
packages.Add(packageName);
var package = PlatformServices.Default.LibraryManager.GetLibrary(packageName);
if (package != null)
{
foreach (var dependency in package.Dependencies)
{
TrackPackage(dependency);
}
foreach (var asm in package.Assemblies)
{
TrackAssembly(asm);
}
}
}
}
private static HashSet<string> assemblies = new HashSet<string>();
private static HashSet<string> packages = new HashSet<string>();
private static Dictionary<string, Assembly> types = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
private static void TrackAssembly(AssemblyName assemblyname)
{
if (!assemblies.Contains(assemblyname.FullName))
{
assemblies.Add(assemblyname.FullName);
var assembly = Assembly.Load(assemblyname);
TrackAssembly(assembly);
}
}
private static void TrackAssembly(Assembly assembly)
{
if (assembly != null)
{
try
{
// Console.WriteLine(assembly.Location);
// Console.WriteLine(assembly.ExportedTypes.Count());
foreach (var type in assembly.ExportedTypes)
{
TrackType(type.FullName, assembly);
}
}
catch (System.IO.FileNotFoundException)
{
Debug.WriteLine("Could not track assembly {0}", assembly.Location);
}
}
}
private static void TrackType(string typeName, Type type)
{
TrackType(typeName, type.GetTypeInfo().Assembly);
}
private static void TrackType(string typeName,Assembly assembly)
{
if (!types.ContainsKey(typeName))
{
types.Add(typeName, assembly);
}
}
}
}
+509
View File
@@ -0,0 +1,509 @@
namespace Microsoft.PowerShell.Linux.Host
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Text;
/// <summary>
/// A sample implementation of the PSHostUserInterface abstract class for
/// console applications. Not all members are implemented. Those that are
/// not implemented throw a NotImplementedException exception or return
/// nothing. Members that are implemented include those that map easily to
/// Console APIs and a basic implementation of the prompt API provided.
/// </summary>
internal class MyHostUserInterface : PSHostUserInterface, IHostUISupportsMultipleChoiceSelection
{
/// <summary>
/// A reference to the PSRawUserInterface implementation.
/// </summary>
private MyRawUserInterface myRawUi = new MyRawUserInterface();
/// <summary>
/// Gets an instance of the PSRawUserInterface class for this host
/// application.
/// </summary>
public override PSHostRawUserInterface RawUI
{
get { return this.myRawUi; }
}
/// <summary>
/// Prompts the user for input.
/// <param name="caption">The caption or title of the prompt.</param>
/// <param name="message">The text of the prompt.</param>
/// <param name="descriptions">A collection of FieldDescription objects
/// that describe each field of the prompt.</param>
/// <returns>A dictionary object that contains the results of the user
/// prompts.</returns>
public override Dictionary<string, PSObject> Prompt(
string caption,
string message,
Collection<FieldDescription> descriptions)
{
this.Write(
ConsoleColor.White,
ConsoleColor.Black,
caption + "\n" + message + " ");
Dictionary<string, PSObject> results =
new Dictionary<string, PSObject>();
foreach (FieldDescription fd in descriptions)
{
string[] label = GetHotkeyAndLabel(fd.Label);
this.WriteLine(label[1]);
string userData = Console.ReadLine();
if (userData == null)
{
return null;
}
results[fd.Name] = PSObject.AsPSObject(userData);
}
return results;
}
/// <summary>
/// Provides a set of choices that enable the user to choose a
/// single option from a set of options.
/// </summary>
/// <param name="caption">Text that proceeds (a title) the choices.</param>
/// <param name="message">A message that describes the choice.</param>
/// <param name="choices">A collection of ChoiceDescription objects that
/// describ each choice.</param>
/// <param name="defaultChoice">The index of the label in the Choices
/// parameter collection. To indicate no default choice, set to -1.</param>
/// <returns>The index of the Choices parameter collection element that
/// corresponds to the option that is selected by the user.</returns>
public override int PromptForChoice(
string caption,
string message,
Collection<ChoiceDescription> choices,
int defaultChoice)
{
// Write the caption and message strings in Blue.
this.WriteLine(
ConsoleColor.Blue,
ConsoleColor.Black,
caption + "\n" + message + "\n");
// Convert the choice collection into something that is
// easier to work with. See the BuildHotkeysAndPlainLabels
// method for details.
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]));
// Read prompts until a match is made, the default is
// chosen, or the loop is interrupted with ctrl-C.
while (true)
{
this.WriteLine(ConsoleColor.Cyan, ConsoleColor.Black, sb.ToString());
string data = Console.ReadLine().Trim().ToUpper();
// 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;
}
}
this.WriteErrorLine("Invalid choice: " + data);
}
}
#region IHostUISupportsMultipleChoiceSelection Members
/// <summary>
/// Provides a set of choices that enable the user to choose a one or
/// more options from a set of options.
/// </summary>
/// <param name="caption">Text that proceeds (a title) the choices.</param>
/// <param name="message">A message that describes the choice.</param>
/// <param name="choices">A collection of ChoiceDescription objects that
/// describ each choice.</param>
/// <param name="defaultChoices">The index of the label in the Choices
/// parameter collection. To indicate no default choice, set to -1.</param>
/// <returns>The index of the Choices parameter collection element that
/// corresponds to the option that is selected by the user.</returns>
public Collection<int> PromptForChoice(
string caption,
string message,
Collection<ChoiceDescription> choices,
IEnumerable<int> defaultChoices)
{
// Write the caption and message strings in Blue.
this.WriteLine(
ConsoleColor.Blue,
ConsoleColor.Black,
caption + "\n" + message + "\n");
// Convert the choice collection into something that is
// easier to work with. See the BuildHotkeysAndPlainLabels
// method for details.
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]));
}
Collection<int> defaultResults = new Collection<int>();
if (defaultChoices != null)
{
int countDefaults = 0;
foreach (int defaultChoice in defaultChoices)
{
++countDefaults;
defaultResults.Add(defaultChoice);
}
if (countDefaults != 0)
{
sb.Append(countDefaults == 1 ? "[Default choice is " : "[Default choices are ");
foreach (int defaultChoice in defaultChoices)
{
sb.AppendFormat(
CultureInfo.CurrentCulture,
"\"{0}\",",
promptData[0, defaultChoice]);
}
sb.Remove(sb.Length - 1, 1);
sb.Append("]");
}
}
this.WriteLine(
ConsoleColor.Cyan,
ConsoleColor.Black,
sb.ToString());
// Read prompts until a match is made, the default is
// chosen, or the loop is interrupted with ctrl-C.
Collection<int> results = new Collection<int>();
while (true)
{
ReadNext:
string prompt = string.Format(CultureInfo.CurrentCulture, "Choice[{0}]:", results.Count);
this.Write(ConsoleColor.Cyan, ConsoleColor.Black, prompt);
string data = Console.ReadLine().Trim().ToUpper();
// If the choice string was empty, no more choices have been made.
// If there were no choices made, return the defaults
if (data.Length == 0)
{
return (results.Count == 0) ? defaultResults : results;
}
// 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)
{
results.Add(i);
goto ReadNext;
}
}
this.WriteErrorLine("Invalid choice: " + data);
}
}
#endregion
/// <summary>
/// Prompts the user for credentials with a specified prompt window
/// caption, prompt message, user name, and target name. In this
/// example this functionality is not needed so the method throws a
/// NotImplementException exception.
/// </summary>
/// <param name="caption">The caption for the message window.</param>
/// <param name="message">The text of the message.</param>
/// <param name="userName">The user name whose credential is to be
/// prompted for.</param>
/// <param name="targetName">The name of the target for which the
/// credential is collected.</param>
/// <returns>Throws a NotImplementedException exception.</returns>
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// Prompts the user for credentials by using a specified prompt window
/// caption, prompt message, user name and target name, credential
/// types allowed to be returned, and UI behavior options. In this
/// example this functionality is not needed so the method throws a
/// NotImplementException exception.
/// </summary>
/// <param name="caption">The caption for the message window.</param>
/// <param name="message">The text of the message.</param>
/// <param name="userName">The user name whose credential is to be
/// prompted for.</param>
/// <param name="targetName">The name of the target for which the
/// credential is collected.</param>
/// <param name="allowedCredentialTypes">A PSCredentialTypes constant
/// that identifies the type of credentials that can be returned.</param>
/// <param name="options">A PSCredentialUIOptions constant that
/// identifies the UI behavior when it gathers the credentials.</param>
/// <returns>Throws a NotImplementedException exception.</returns>
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options)
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// Reads characters that are entered by the user until a newline
/// (carriage return) is encountered.
/// </summary>
/// <returns>The characters that are entered by the user.</returns>
public override string ReadLine()
{
return Console.ReadLine();
}
/// <summary>
/// Reads characters entered by the user until a newline (carriage return)
/// is encountered and returns the characters as a secure string. In this
/// example this functionality is not needed so the method throws a
/// NotImplementException exception.
/// </summary>
/// <returns>Throws a NotImplemented exception.</returns>
public override System.Security.SecureString ReadLineAsSecureString()
{
throw new NotImplementedException("The method or operation is not implemented.");
}
/// <summary>
/// Writes characters to the output display of the host.
/// </summary>
/// <param name="value">The characters to be written.</param>
public override void Write(string value)
{
Console.Write(value);
}
/// <summary>
/// Writes characters to the output display of the host with possible
/// foreground and background colors.
/// </summary>
/// <param name="foregroundColor">The color of the characters.</param>
/// <param name="backgroundColor">The backgound color to use.</param>
/// <param name="value">The characters to be written.</param>
public override void Write(
ConsoleColor foregroundColor,
ConsoleColor backgroundColor,
string value)
{
Console.ForegroundColor = foregroundColor;
Console.BackgroundColor = backgroundColor;
Console.Write(value);
//Console.Write(value);
Console.ResetColor();
}
/// <summary>
/// Writes a line of characters to the output display of the host
/// with foreground and background colors and appends a newline (carriage return).
/// </summary>
/// <param name="foregroundColor">The forground color of the display. </param>
/// <param name="backgroundColor">The background color of the display. </param>
/// <param name="value">The line to be written.</param>
public override void WriteLine(
ConsoleColor foregroundColor,
ConsoleColor backgroundColor,
string value)
{
Console.ForegroundColor = foregroundColor;
Console.BackgroundColor = backgroundColor;
Console.WriteLine(value);
Console.ResetColor();
}
/// <summary>
/// Writes a debug message to the output display of the host.
/// </summary>
/// <param name="message">The debug message that is displayed.</param>
public override void WriteDebugLine(string message)
{
this.WriteLine(
ConsoleColor.Yellow,
ConsoleColor.Black,
String.Format(CultureInfo.CurrentCulture, "DEBUG: {0}", message));
}
/// <summary>
/// Writes an error message to the output display of the host.
/// </summary>
/// <param name="value">The error message that is displayed.</param>
public override void WriteErrorLine(string value)
{
this.WriteLine(
ConsoleColor.Red,
ConsoleColor.Black,
value);
}
/// <summary>
/// Writes a newline character (carriage return)
/// to the output display of the host.
/// </summary>
public override void WriteLine()
{
Console.WriteLine();
}
/// <summary>
/// Writes a line of characters to the output display of the host
/// and appends a newline character(carriage return).
/// </summary>
/// <param name="value">The line to be written.</param>
public override void WriteLine(string value)
{
Console.WriteLine(value);
}
/// <summary>
/// Writes a progress report to the output display of the host.
/// </summary>
/// <param name="sourceId">Unique identifier of the source of the record. </param>
/// <param name="record">A ProgressReport object.</param>
public override void WriteProgress(long sourceId, ProgressRecord record)
{
}
/// <summary>
/// Writes a verbose message to the output display of the host.
/// </summary>
/// <param name="message">The verbose message that is displayed.</param>
public override void WriteVerboseLine(string message)
{
this.WriteLine(
ConsoleColor.Green,
ConsoleColor.Black,
String.Format(CultureInfo.CurrentCulture, "VERBOSE: {0}", message));
}
/// <summary>
/// Writes a warning message to the output display of the host.
/// </summary>
/// <param name="message">The warning message that is displayed.</param>
public override void WriteWarningLine(string message)
{
this.WriteLine(
ConsoleColor.Yellow,
ConsoleColor.Black,
String.Format(CultureInfo.CurrentCulture, "WARNING: {0}", message));
}
/// <summary>
/// Parse a string containing a hotkey character.
/// Take a string of the form
/// Yes to &amp;all
/// and returns a two-dimensional array split out as
/// "A", "Yes to all".
/// </summary>
/// <param name="input">The string to process</param>
/// <returns>
/// A two dimensional array containing the parsed components.
/// </returns>
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();
}
result[1] = (fragments[0] + fragments[1]).Trim();
}
else
{
result[1] = input;
}
return result;
}
/// <summary>
/// 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 &amp; removed.
/// </summary>
/// <param name="choices">The choice collection to process</param>
/// <returns>
/// A two dimensional array containing the accelerator characters
/// and the cleaned-up labels</returns>
private static string[,] BuildHotkeysAndPlainLabels(
Collection<ChoiceDescription> choices)
{
// 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;
}
}
}