◐ Shell
clean mode source ↗

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>

@SufficientDaikon

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>

@kilasuit kilasuit added WG-Engine

core PowerShell engine, interpreter, and runtime

CL-Engine

Indicates that a PR should be marked as an engine change in the Change Log

WG-NeedsReview

Needs a review by the labeled Working Group

labels

Mar 28, 2026
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>

daxian-dbw

daxian-dbw

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>

@SufficientDaikon