Fix -WindowStyle Hidden console window flash by SufficientDaikon · Pull Request #27111 · PowerShell/PowerShell
Use consoleAllocationPolicy=detached manifest and AllocConsoleWithOptions to prevent the OS from auto-allocating a visible console window on newer Windows. On older Windows the manifest is ignored and behavior is unchanged. On Windows 11 build 26100+, the detached policy stops the OS from creating a console window before any code runs. PowerShell now allocates the console itself at the earliest point in startup — visibly for interactive use, or invisibly via AllocConsoleWithOptions(NoWindow) when -WindowStyle Hidden is specified. This approach was recommended by @DHowett (Windows Console team) in PowerShell#3028 (comment) Fix PowerShell#3028
- Replace Substring(1) with AsSpan(1) for zero-alloc early arg parsing - Extract TryAllocConsoleNoWindow() into Interop.Windows (DRY) - Add XML doc comments to AllocConsoleWithOptions enums and struct - Document colon-syntax and false-positive behavior in arg scanner - Change test tag from CI to Feature (matches existing WindowStyle tests) - Remove hardcoded build number from API probe test - Add -ErrorAction Stop to Add-Type in tests - Use double quotes consistently in test file
Per DHowett's feedback: plain AllocConsole() overrides DETACHED_PROCESS from the parent's CreateProcess call. AllocConsoleWithOptions with Default mode respects it. Extract shared TryAllocConsoleWithMode() and add TryAllocConsoleDefault() alongside TryAllocConsoleNoWindow(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The early arg scan only stripped one leading dash, so --windowstyle hidden was not detected (the key became "-windowstyle" with length 12, failing the <= "windowstyle".Length check). Add double-dash stripping to match the full parser's GetSwitchKey behavior. Remove misleading comment claiming colon syntax is handled by the full parser (GetSwitchKey does not split on colons for windowstyle). Rewrite manifest test to extract embedded manifest from PE binary instead of checking a source file that doesn't exist in $PSHOME. Add 5 early arg scan variant tests: -w, -win, --windowstyle, /windowstyle, UPPERCASE. Total: 12 Pester tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
labels
CI uses Pester 4.x which does not support -Skip on Context blocks, causing 'A parameter cannot be found that matches parameter name Skip' on all three platforms. Move -Skip:(!$IsWindows) to individual It blocks (standard pattern). Also addresses Copilot review feedback: - Add CI tag so tests run in standard CI (not just Others) - Remove Assembly::LoadFile path (pwsh.exe is native, not managed) - Use repo-relative path via $PSScriptRoot for manifest fallback - Add return after Set-ItResult -Skipped per Pester guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
EarlyConsoleInit: remove early ShowWindow(SW_HIDE) for existing consoles per daxian-dbw — leave -WindowStyle handling to the existing SetConsoleMode code path. EarlyConsoleInit now only handles the no-console case. TryAllocConsoleWithMode: check AllocConsoleResult instead of discarding it. Return false when result is NoConsole (DETACHED_PROCESS respected) so callers know a console was not actually allocated. NativeCommandProcessor: add comment clarifying foreground window restore runs for both NoWindow and fallback paths. Manifest: add XML comment explaining why asm.v3 xmlns is required on the application element (distinct from root asm.v1 namespace). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters