|
Thursday, June 22, 2006
Enter Nested Prompt function
PowerShell Remoting,
What did it do?
In windows PowerShell, $Host object provides direct access to some important APIs. One of the interesting functions is $Host.EnterNestedPrompt(). Frankly speaking, it did not appeal to me at all when I first tried it. But I discovered this beauty after I implemented my own PSHost in What did it do?
- Suspend & Save current execution context state.
- Create a new nested execution context.(Nested pipline, new prompt execution helper and new script excution helper)
- Push the new nested execution context to stack. (PowerShell use a static stack. In my PowerShell Remoting, it is more complicate. Every client has its own host; every host has its own stack for nested prompt.)
- Increase $NESTEDPROMPTLEVEL
- Your current pipeline is suspended. All variables and errors state were saved.
- In the meantime, you still have access to monad engine. You can have new prompt, run new script or other interactive command.
- When you are done with the new scope, you can call invoke $Host.ExitNestedPrompt() or "exit" (which will call $Host.ExitNestedPrompt()) to return to previous pipeline.
- First, Let's see how "Suspend" works when using -confirm option or "Set-PSDebug -Step"
- Secondly, $Host.EnterNestedPrompt() can be used as break point when debugging your script. To make a break point, you can add $Host.EnterNestedPrompt() at anywhere in your script. When your script execute to it, you will have a nested prompt to explore variables and errors at this break point.
> kill 2804 -ConfirmWhen you choose [S]Suspend, you actually called $Host.EnterNestedPrompt() which break current script and provide you an nested prompt.
Confirm
Are you sure you want to perform this action?
Performing operation "Stop-Process" on Target "Notepad (2804)".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is "Y"):
> Set-PSDebug -Step
> D:\ps1\special.ps1
Continue with this operation?
1+ D:\ps1\special.ps1
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is "Y"):
> 1..10 | %{if($_ -eq 5) {$host.EnterNestedPrompt()};$_}
1
2
3
4
>>> $_
5
>>> exit
5
6
7
8
9
10
- Nested prompt and original prompt share same variables provider. So when you change a variable in nested prompt, the change will remain effective in original prompt.
- Comannd will be written in history when it is completed. So a suspended command will not be found in history.
- The maximum depth of nested prompt level ($NESTEDPROMPTLEVEL) is 128. So always check $NESTEDPROMPTLEVEL for current nested prompt level. You can write it into your prompt function.
- Do not try to make a nested function using $Host.EnterNestedPrompt(). But you can always do this.
function factorial
{
param ([int]$n = 1)
if ($n -le 0)
{
"Invalid parameter."
return
}
if ($n -eq 1)
{
return 1
}
return $n * (factorial ($n-1))
}
Tags: msh monad PowerShell
Comments:
<< Home
Great stuff there, Tony!
I have never realized that suspending current cmdlet operation would result in calling nested prompt(although i do show nested prompt level in my "prompt"...)
And also, being able to use Nested Prompt for debugging (since you have mentioned that in the nested level, all of the parent's variables are "saved"...
I have never realized that suspending current cmdlet operation would result in calling nested prompt(although i do show nested prompt level in my "prompt"...)
And also, being able to use Nested Prompt for debugging (since you have mentioned that in the nested level, all of the parent's variables are "saved"...
<< Home
Post a Comment