Skip to content

System.Diagnostics.Process.GetProcessById() returns Process objects for non-running processes #66096

@PaulHigin

Description

@PaulHigin

Description

PowerShell uses System.Diagnostics.Process.GetProcessById API to obtain process information about running processes. Before .NET 7.0.100-preview.1.22110.4, this API would throw a System.ArgumentException for non-existent processes or for processes that have recently exited. But with .NET 7, this API now sometimes returns a process object for non-running processes with HasExited set to True.

This is a change in behavior that has caused some PowerShell tests to fail.

Reproduction Steps

  1. Start two instances of PowerShell shell, of the latest preview (7.3.0-preview.2).
  2. This preview version of PowerShell is built with .NET version 7.0.100-preview.1.22110.4
  3. Get the two instances process Ids by typing $PID in each shell version.
PS > $PID
31412
PS > $PID
24672
  1. In one shell instance get the process object of the other instance via .NET API
PS > $PID
31412
PS > [System.Diagnostics.Process]::GetProcessById(24672)

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
     70    54.65      96.04       2.91   24672   2 pwsh
  1. Exit the PowerShell instance with process Id 24672, and use the .NET API again to obtain the process object.
PS > [System.Diagnostics.Process]::GetProcessById(24672)

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00       0.00       3.08   24672

PS > ([System.Diagnostics.Process]::GetProcessById(24672)).HasExited
True

Expected behavior

System.Diagnostics.Process.GetProcessById(24672) should not return a process object for a non-running process, and should instead throw an ArgumentException error.

PS C:\> [System.Diagnostics.Process]::GetProcessById(24672)
MethodInvocationException: Exception calling "GetProcessById" with "1" argument(s): "Process with an Id of 24672 is not running."

Actual behavior

The API returns a process object for a non-existent process

PS C:\> [System.Diagnostics.Process]::GetProcessById(24672)

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00       0.00       3.08   24672

PS C:\> ([System.Diagnostics.Process]::GetProcessById(24672)).HasExited
True

Regression?

Yes, this is a regression in behavior to .NET 6.

Known Workarounds

We can update PowerShell code account for this behavior, but it is not clear if this change in behavior is intended or correct.

Configuration

.NET version:
7.0.100-preview.1.22110.4

PowerShell:

PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.3.0-preview.2
PSEdition                      Core
GitCommitId                    7.3.0-preview.2-9-gee6bc9527c2596f048088fa7b396d2664a11ad08
OS                             Microsoft Windows 10.0.19044
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions