PowerShell Remoting Project Home

Tuesday, March 14, 2006

Separation of Monad Engine and User Interface

Research on MshHost & MshHostUserInterface abstract class.

The msh.exe is actully a console program hosting monad engine. In another word: monad engine does not worry about user interface, it is host environment's job.  My Remote MSH server is not INTERACTIVE (For example: remote user will not be prompted to input credentials when invoking "get-credential" at server) because I use DefaultHost which does not Implement MshHostUserInterface

OK, OK, it is to fast, let's start from Create a Runspace:
System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace()
public static Runspace CreateRunspace()
{
      Runspace runspace1;
      using (IDisposable disposable1 = RunspaceFactory._tracer.TraceMethod())
      {
            runspace1 = RunspaceFactory.CreateRunspace(new DefaultHost(Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.CurrentUICulture));
      }
      return runspace1;
}
So it acually create a Runspace using DefaultHost
Microsoft.Management.Automation.Internal.DefaultHost is a implement of MshHost abstract class.
internal class DefaultHost : MshHost
{
      // Methods
      static DefaultHost();
      internal DefaultHost(CultureInfo currentCulture, CultureInfo currentUICulture);
      public override void EnterNestedPrompt();
      public override void ExitNestedPrompt();
      public override void NotifyBeginApplication();
      public override void NotifyEndApplication();
      public override void SetShouldExit(int exitCode);

      // Properties
      public override CultureInfo CurrentCulture { get; }
      public override CultureInfo CurrentUICulture { get; }
      public override Guid InstanceId { get; }
      public override string Name { get; }
      public override MshHostUserInterface UI { get; }
      public override Version Version { get; }

      // Fields
      private CultureInfo currentCulture;
      private CultureInfo currentUICulture;
      private Guid id;
      [TraceSource("DefaultHost", "DefaultHost subclass of S.M.A.MshHost Tracer")]
      private static MshTraceSource tracer;
      private Version ver;
}
Let's take a look at System.Management.Automation.Host.MshHost
public abstract class MshHost
{
      // Methods
      protected MshHost();
      public abstract void EnterNestedPrompt();
      public abstract void ExitNestedPrompt();
      public abstract void NotifyBeginApplication();
      public abstract void NotifyEndApplication();
      public abstract void SetShouldExit(int exitCode);

      // Properties
      public abstract CultureInfo CurrentCulture { get; }
      public abstract CultureInfo CurrentUICulture { get; }
      public abstract Guid InstanceId { get; }
      public abstract string Name { get; }
      public virtual MshObject PrivateData { get; }
      public abstract MshHostUserInterface UI { get; }
      public abstract Version Version { get; }
}
MshHostUserInterface is the object which actully deals with user interface:
public abstract class MshHostUserInterface
{
      // Methods
      protected MshHostUserInterface();
      public abstract Dictionary<string, MshObject> Prompt(string caption, string message, Collection<FieldDescription> descriptions);
      public abstract int PromptForChoice(string caption, string message, Collection<ChoiceDescription> choices, int defaultChoice);
      public abstract MshCredential PromptForCredential(string caption, string message, string userName, string targetName);
      public abstract MshCredential PromptForCredential(string caption, string message, string userName, string targetName, MshCredentialTypes allowedCredentialTypes, MshCredentialUIOptions options);
      public abstract string ReadLine();
      public abstract SecureString ReadLineAsSecureString();
      public abstract void Write(string value);
      public abstract void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value);
      public abstract void WriteDebugLine(string message);
      public abstract void WriteErrorLine(string value);
      public virtual void WriteLine();
      public abstract void WriteLine(string value);
      public virtual void WriteLine(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value);
      public abstract void WriteProgress(long sourceId, ProgressRecord record);
      public abstract void WriteVerboseLine(string message);
      public abstract void WriteWarningLine(string message);

      // Properties
      public abstract MshHostRawUserInterface RawUI { get; }
}
But when we check the public property UI in DefaultHost:
public override MshHostUserInterface UI
{
      get
      {
            MshHostUserInterface interface1;
            using (IDisposable disposable1 = DefaultHost.tracer.TraceProperty())
            {
                  interface1 = null;
            }
            return interface1;
      }
}
So, it is a null object.

If we want a REAL interactive remote shell, we have to implement our own MshHost and MshHostUserInterface (and maybe MshHostRawUserInterface). MshHostUserInterface will be responsible to write results to and get input from remote client. I bet this is the way Microsoft monad team will be using to provide remote access (maybe in version 2 of msh).

For me, it is too much work (and I would not compete with monad team). I really wish someone can show a example of implementation of MshHost and MshHostUserInterface. Maybe monad team would like to share their  source code of msh.exe

Hehe, You know I am joking, right?

Added on Mar 15th 10:50am
I just find out that Microsoft Command Shell (MSH) Programmer's Guide are online now! It has exact information I needed.

Have Fun!

Tags:    


Comments:
hey, if you really want to get lost in monad's code (ok, at least during the first hours :) ), you can do like the rest of us and use the phenomenal .net reflector by lutz roeder
 
Who knows where to download XRumer 5.0 Palladium?
Help, please. All recommend this program to effectively advertise on the Internet, this is the best program!
 

Post a Comment





<< Home