FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Launching `pwsh.exe` without a console (`DETACHED_PROCESS`) results in quiet startup failure · Issue #28383 · PowerShell/PowerShell · GitHub

Repository navigation

Launching pwsh.exe without a console (DETACHED_PROCESS) results in quiet startup failure #28383

Open

Description

Prerequisites

Steps to reproduce

Launching a process with the DETACHED_PROCESS flag of the WinAPI CreateProcess() function by design does so without a console, even for console-subsystem applications.

However, pwsh.exe assumes the presence of a console and quietly aborts if it cannot find one: exit code 0 is reported, and no WER (Windows Error Reporting) event is recorded in the Windows Application event log.

Note:

  • SCM, the Windows Service Control Manager, is an example of a component that starts (service) executables with DETACHED_PROCESS; while using pwsh.exe as a service executable is not a common use case, it is possible to implement a service via a .ps1 script passed to pwsh.exe -File - see this Stack Overflow post.

  • There are two ways to fix this problem:

    • Report a nonzero exit code and log a WER event with a specific error message - this is what the repro below assumes.

    • Alternatively, allow PowerShell to run without a console: infer non-interactive mode in the absence of a console and prevent attempts to access console-specific features in a controlled manner (note that the -noninteractive CLI option does not currently do that).

  • The following repro code requires .NET 11+ / at least a PowerShell 7.7 preview version, due to use of the new .StartDetached property of ProcessStartInfo.

using namespace System.Diagnostics

$startTime = [System.DateTime]::Now

# Start PowerShell without a console (DETACHED_PROCESS)
# Note: Requires .NET 11+
[Process]::Start(
  [ProcessStartInfo] @{
    FileName = 'pwsh.exe'
    Arguments = '-c "Start-Sleep 5"'
    StartDetached = $true
  }
) | Wait-Process -PassThru | Select-Object *Exit*

"Ran for $('{0:N1}' -f ([datetime]::Now - $startTime).TotalSeconds) secs." | Out-Host

# # As a crosscheck, use the following to provoke a crash that DOES create a WER event.
# $ps = Start-Process -PassThru conhost.exe (Get-Process -Id $PID).Path; Start-Sleep 2; $ps | Stop-Process

"Sleeping a little, to give a WER event time to show up" | Out-Host
1..5 | ForEach-Object { Write-Host -NoNewline .; Start-Sleep 1 }
Write-Host

# Report the resulting WER event, if any.
Get-WinEvent -FilterHashTable @{
  ProviderName = 'Windows Error Reporting'
  Id           = 1001
  Data = 'pwsh.exe' # matches the <Data Name="P1"> sub-element of <EventData>
  StartTime    = $startTime # events written since this [datetime] instance; supplemnt with `EndTime`, if needed
} | Format-List

The offending parts of the source code:

  • private static readonly Lazy<ConsoleHandle> _outputHandle = new Lazy<SafeFileHandle>(() =>
    {
    // We use CreateFile here instead of GetStdWin32Handle, as GetStdWin32Handle will return redirected handles
    var handle = NativeMethods.CreateFile(
    "CONOUT$",
    (UInt32)(NativeMethods.AccessQualifiers.GenericRead | NativeMethods.AccessQualifiers.GenericWrite),
    (UInt32)NativeMethods.ShareModes.ShareWrite,
    (IntPtr)0,
    (UInt32)NativeMethods.CreationDisposition.OpenExisting,
    0,
    (IntPtr)0);
    if (handle == NativeMethods.INVALID_HANDLE_VALUE)
    {
    int err = Marshal.GetLastWin32Error();
    HostException e = CreateHostException(err, "RetreiveActiveScreenBufferConsoleHandle",
    ErrorCategory.ResourceUnavailable, ConsoleControlStrings.GetActiveScreenBufferHandleExceptionTemplate);
    throw e;
    }
    return new ConsoleHandle(handle, true);
    }
    );
  • // These exceptions are caused by killing conhost.exe
    // 1236, network connection aborted by local system
    // 0x6, invalid console handle
    if (win32e.NativeErrorCode == 0x6 || win32e.NativeErrorCode == 1236)
    {
    return exitCode;
    }

Expected behavior

Ran for 10.0 secs.
.....
ExitCode HasExited ExitTime
-------- --------- --------
       1      True <timestamp>
<tabular display of a WER event-log entry with a specific error message>

Actual behavior

Ran for 0.3 secs.
.....
ExitCode HasExited ExitTime
-------- --------- --------
       0      True <timestamp>
Get-WinEvent: foo.ps1:25
Line |
  25 |  Get-WinEvent -FilterHashTable @{
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | No events were found that match the specified selection criteria.

That is:

  • the Start-Sleep command passed to -c never got to execute
  • the exit code was unexpectedly 0
  • no WER event was logged.

Error details

Environment data

PowerShell Core v7.7.0-preview.5 on Windows

Visuals

No response

Activity

  1. iSazonov commented on Nov 10, 2026

    Collaborator

    Apparently you need to run the detached process in Server Mode.

  2. jessehouwing commented on Nov 10, 2026

    Apparently you need to run the detached process in Server Mode.

    Server mode doesn't allow you to pass the start-up script as an argument from what I can tell.

  3. mklement0 commented on Nov 10, 2026

    ContributorAuthor

    Good point, Jesse Houwing (@jessehouwing) - a run-given-code-then-exit CLI call is fundamentally different from putting pwsh.exe into a server mode.

    Apart from that, Ilya (@iSazonov): Among the various server modes:

    • Only -namedpipeservermode appears to run normally.
    • -servermode and -shhservermode fail right away, but predictably so , given that they rely on stdin, which isn't available with DETACHED_PROCESS; confusingly, the exit code is 0xFA0, however - no WER event is logged.
    • -socketservermode crashes after a couple of seconds, via .FailFast() (which creates 2 .NET event-log events plus a WER one), due to Failed to create an instance of RemoteSessionHyperVSocketServe, with exit code 0x80131623.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageThe issue is new and needs to be triaged by a work group.WG-Interactive-Consolethe console experience

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL