Monday, June 28, 2004

I have been wondering about the cmdlet lifecycle. 

 

How do you add a new cmdlet?

How are the cmdlets loaded by MSH?

 

You use registercommand.exe <Path/dllname> and the new dll is registered. Now what happens when msh is started again? Does it load all the dlls in memory? Or does it load it when a cmdlet in the dll is explicitly invoked? Loading all cmdlet dlls in memory seems like too much memory consumption and overhead. The converse argument could be that practically the number of cmdlets wouldn’t be a very huge number; so doing this at start would give a performance hit.

 

Then again, when do we design stuff for pracrtical cases alone, we usually think of the worst cases!

 

Well, so how do you really find out how MSH is handling commandlet life cycle? There is no cordbg for .Net 2.0 yet and no CLR profilers in the picture.

 

There still is filemon.exe. Thanks to filemon.exe, these are my observations.

 

  1. All the cmdlet dlls are not loaded at msh start up.
  2. get-command doesn’t use reflection on all dlls’ to get all cmdlet names.
  3. Typing a specific cmdlet name loads the corresponding dll, processes and closes it

 These observations lead to the following conclusions:

 

  1. At start-up, msh does not load all the cmdlets in memory
  2. On typing get-command, it does a look-up [may be something like a file lookup], finds all the cmdlet name entries and outputs them
  3. On typing a specific cmdlet at the msh prompt, the corresponding dll is loaded by msh, the processing done, results obtained and dll unloaded [I think]
  4. Due to caching, all cmdlets take time during their first invocation and are faster thereafter.

 

How is a cmdlet executed?

 

First the corresponding dll is found and loaded. Then the cmdlet class is instantiated.

StartProcessing() if overrid is executed. If there are any input parameters, then they are filled with the values by msh and passed to ProcessRecord() if one exists. If pipelined input is enabled then the input parameter is filled with the current pipeline object and ProcessRecord() is exceuted for each of the input records. [So, this kind of looping is not the cmdlet’s responsibility, msh handles it and pumps in the value each time into the input parameter variable]. Finally if EndProcessing() is overrid, then it is executed. The object is then disposed off. Msh handles the output display/formatting/piping/redirection.

 

DISCLAIMER: These are my views only. This is not documented stuff, so I am just taking a guess as to how things may be working under the cover. I could be wrong!

Monday, June 28, 2004 1:15:42 PM (US Eastern Standard Time, UTC-05:00)  #    Comments [0]Trackback
Name
E-mail
Home page

Comment (Some html is allowed: )  

Enter the code shown (prevents robots):