|
Tuesday, March 14, 2006
Separation of Monad Engine and User Interface
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()So it acually create a Runspace using DefaultHost
{
Runspace runspace1;
using (IDisposable disposable1 = RunspaceFactory._tracer.TraceMethod())
{
runspace1 = RunspaceFactory.CreateRunspace(new DefaultHost(Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.CurrentUICulture));
}
return runspace1;
}
Microsoft.Management.Automation.Internal.DefaultHost is a implement of MshHost abstract class.
internal class DefaultHost : MshHostLet's take a look at System.Management.Automation.Host.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;
}
public abstract class MshHostMshHostUserInterface is the object which actully deals with user interface:
{
// 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; }
}
public abstract class MshHostUserInterfaceBut when we check the public property UI in DefaultHost:
{
// 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; }
}
public override MshHostUserInterface UISo, it is a null object.
{
get
{
MshHostUserInterface interface1;
using (IDisposable disposable1 = DefaultHost.tracer.TraceProperty())
{
interface1 = null;
}
return interface1;
}
}
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!
Comments:
<< Home
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!
Help, please. All recommend this program to effectively advertise on the Internet, this is the best program!
<< Home
Post a Comment