With some things cleared up and some ground work done, here is one of the first the things I want to talk about in Monad – the new Microsoft Command Shell(msh).
In my first article I talked about ‘cmdlets’ and that they return .Net objects. Here is one other smart and subtle thing they did with Monad – Parameters to cmdlets come not only on the command line but can also come from objects in the input object pipeline.
Some basic stuff on cmdlets and parameters which might help set the stage for understanding things. A command-let can define fields/member variables as part of the command let class. These fields can then be decorated by attributes so that they can be treated as parameters to the commandlet.
In code it actually looks like this:
[CmdletDeclaration( "demo", "cmdlet" )]
public class HelloWorld : Cmdlet
{
[ParsingPromptString("Enter a string to echo: " )]
[ParsingParameterMapping(0)]
[ParsingMandatoryParameter]
[ParsingAllowPipelineInput]
private string message;
(This snippet is a modified version of code from the beta documentation)
Now this might look a little over decorated with attributes, but the thing I want you to notice is that that is a member called ‘message’ which simply has a few attributes applied. Applying those attributes causes ‘message’ of type System.String to be a parameter required for our command let.
Unlike traditional command line exes, the responsibility of parsing the command line options and assigning them to internal variables is not the responsibility of the program but is automatically done for you by the Monad shell.
Which is to say that by the time code that you write in the cmdlet is executed, values are already assigned to the parameter variables by the shell. (Not strictly, but almost).
The shell can let you assign parameter values either by specifying them at a certain postion in the command line – for example argv[1] will be the value for ‘message’, argv[2] will be the value for something else and so on. Or the shell lets you specify the parameter name and then the value
> demo-cmdlet –message “hello world” -< parameter name > < value >
The other good thing (which is new and what this log entry was about) is that the value for a parameter can be extracted from an object on the pipeline if the object has a field/member of the same name. (The types have to be consistent)
So if I have a command let that generates an object of type foobar that has a member of name ‘message’, I can pipe the output to the commandlet that required a parameter of name ‘message’ and it would all work.
> create-foobar | demo-cmdlet
Would create foorbar instances that get piped to demo-cmdlet which uses the ‘foobar.message’ as its message parameter.
Where would this be used?
For an example there is a command-let called ‘get-process’. It lists the running processes on the system. To be more precise it returns a collection of process instances which get standard formatted to the console.
MSH 5 C:/>get-process
ProcessName Id HandleCount WorkingSet
----------- -- ----------- ----------
CcmExec 288 480 14008320
cmd 804 22 1421312
csrss 464 669 4743168
dfssvc 316 70 3260416
DWRCS 1444 44 2560000
explorer 3520 366 20926464
FrameworkService 1544 303 9367552
Idle 0 0 16384
Similarly to see all the instances of notepad that are running I would simply say
MSH 16 C:/>get-process note*
notepad 3912 16 1912832
notepad 4044 16 1912832
notepad 3056 16 1912832
Now there is a cmdlet called stop-process which can terminate a process if you pass it the process id as a parameter. The parameter name that stop-process expects is called ‘Id’.
MSH 11 C:/>command stop-process
Command: stop-process
Command Parameters:
Id : Int32[] : Optional
ProcessName : String[] : Optional
So with all the earlier talk you can conclude that if I simply wanted to kill all the instances of notepad that are running I could type
MSH 11 C:/>get-process note* | stop-process
Now isn’t that clean? Just to add a bit of garnishing to that, Monad defines ‘ps’ as an alias to get-process and ‘kill’ as an alias to ‘stop-process’.
So now you can say
MSH 11 C:/>ps note* | kill
Cool? This works on Monad today.
Prev:
Introductory entry about Monad
Next:
ObjShell: A precursor of Monad?
Remember Me
a@href@title, strike
Powered by: newtelligence dasBlog 2.0.7226.0
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2008, Roshan James
E-mail