Getting Read-Host right in a GUI host
There’s a classic failure in embedded PowerShell consoles, and it starts with a script asking a question. Read-Host in a GUI host that didn’t plan for it doesn’t error. It waits. The pipeline blocks on input that has nowhere to come from, the window stops responding, and the user reaches for Task Manager. Install-Module was the traditional trigger, with its gallery-trust confirmation prompt. A generation of embedded consoles froze on it.
In DetentShell, interactive prompts are a protocol. When a running script calls Read-Host, the pipeline thread pauses, which is PowerShell’s contract and can’t be avoided. But the pause happens against a bridge: the request gets a correlation ID, crosses to the UI as an event, and shows up as a normal dialog while the window keeps painting and responding. Your answer travels back to the exact pipeline that asked. Cancel the dialog and the wait unwinds as a clean cancellation.
The bridge covers the whole prompt family. Plain Read-Host. Read-Host -AsSecureString with masked input, where the text is a SecureString from the keystroke onward and never sits in a plain string. Get-Credential. Mandatory-parameter prompts, which are the common case nobody thinks about: forget a required argument and PowerShell asks for it, so the workbench renders the field form instead of hanging. Choice prompts, the Yes/No/Suspend kind, render with their options and default.
The correlation IDs earn their existence in one scenario: two sessions blocked on prompts at the same time. Sessions are independent here, so that’s not exotic. Each answer routes to the pipeline that asked and no other. An implementation that assumed one outstanding prompt would demo fine and misroute in the field.
One boundary gets named rather than hidden. Live Windows PowerShell 5.1 sessions run out-of-process, and certain interactive surfaces can’t cross that boundary faithfully. Where one can’t, the run fails with a single sentence saying interactive prompts aren’t supported on that path. Between a hang and a sentence, we ship the sentence.
The test suite runs these round-trips with a scripted answerer on the other side: ask, answer, verify the value landed, cancel, verify the unwind. “The app doesn’t freeze” is not a claim we were willing to leave to demos.