Skip to content

Get-Process return closed(stoped) process #12880

Closed

Description

Steps to reproduce

$proc = Start-Process notepad++ -PassThru
Get-Process -Id $proc.Id
Stop-Process $proc
get-process -Id $proc.Id

Expected behavior

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      3     0,56       1,89       0,02    5996   7 notepad++
Get-Process: untitled:Untitled-1:4:1
Line |
   4 |  get-process -Id $proc.Id
     |  ~~~~~~~~~~~~~~~~~~~~
     | Cannot find a process with the process identifier 1598.

Actual behavior

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      3     0,57       1,86       0,05    5580   7 notepad++
      0     0,00       0,00       0,08    5580

Environment data

Name                           Value
----                           -----
PSVersion                      7.0.1
PSEdition                      Core
GitCommitId                    7.0.1
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Activity

  1. added
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on Jun 3, 2020
  2. vexx32 commented on Jun 3, 2020

    @vexx32
    Collaborator

    This might just be a timing issue, retrieving the process before it's finished shutting down. Killing a process isn't always instantaneous.

    Does it still reproduce if you have a slight wait before calling the final Get-Process?

  3. Sidoran commented on Jun 3, 2020

    @Sidoran
    Author

    This issue are reproduced after a several minutes wait.

    $proc = Start-Process notepad++ -PassThru
    Get-Process -Id $proc.Id
    Stop-Process $proc
    Start-Sleep 180
    get-process -Id $proc.Id
    

    Return the same.
    On powershell 5.1 everything works fine

  4. vexx32 commented on Jun 3, 2020

    @vexx32
    Collaborator

    Interesting. I'm not seeing the same on MacOS.

    Hard to say if this is a PowerShell or a .NET issue... Can you swap the final step for [System.Diagnostics.Process]::GetProcessById($proc.Id) and see if you get the same?

    We may need to file an issue in the dotnet repository if it still reproduces with only .NET code.

  5. Sidoran commented on Jun 3, 2020

    @Sidoran
    Author
    $proc = Start-Process notepad++ -PassThru
    Get-Process -Id $proc.Id
    Stop-Process $proc
    Start-Sleep 180
    [System.Diagnostics.Process]::GetProcessById($proc.Id)
    

    return the same:

     NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
     ------    -----      -----     ------      --  -- -----------
          3     0,54       1,66       0,08   15536   7 notepad++  
          0     0,00       0,00       0,09   15536     
    
    

    This issue was first found on Windows Server 2012R2

  6. vexx32 commented on Jun 3, 2020

    @vexx32
    Collaborator

    Interesting... The documentation for the Process class mentions that calling Process.Kill() is asynchronous, and if you want to wait for a process to fully exit you can check Process.HasExited or use Process.WaitForExit()

    Looking at the Stop-Process cmdlet code, it looks like it will pretty much always just call Process.Kill() and move on.

    I'm not entirely sure it makes sense for the cmdlet to always wait for each process to exit. It would cause problems if you were passing an array of processes to stop, and a particular process didn't exit, preventing the cmdlet from terminating subsequent processes.

    If anything, I'd suggest we enhance Stop-Process to support:

    • A -Wait switch to wait for the process(es) to exit, and
    • A -WaitTimeout parameter to specify a number of seconds (maybe 3-5 seconds by default?) to wait for process terminations to complete.

    The cmdlet can call Kill() on all the processes, and then wait in a loop with small sleeps in EndProcessing() until either the timeout has elapsed or all processes have exited. If the timeout elapses and some or all processes have not yet terminated, write non-terminating errors for each process that failed to stop.

  7. iSazonov commented on Jun 3, 2020

    @iSazonov
    Collaborator

    We get the info from Process.GetProcessById(). So I think it is Windows behavior.
    You can ask in .Net Runtime repository about this.

  8. KalleOlaviNiemitalo commented on Jun 5, 2020

    @KalleOlaviNiemitalo

    This is a .NET Core bug, mentioned in dotnet/runtime#20725 (comment) and presumably caused by dotnet/corefx#17476, i.e. between .NET Core 1.1.13 and 2.0.0. On .NET Framework 4.8, Process.GetProcessById does not return a process that has already terminated, even if the process object still exists because of process handles.

    Process.UpdateHasExited uses a zero-duration wait on the process handle to check whether the process has terminated. ProcessManager.IsProcessRunning should be changed to do the same.

  9. Sidoran commented on Jun 6, 2020

    @Sidoran
    Author

    I writed a small console app

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    namespace ProcessTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Process testproc = Process.Start(@"C:\\Program Files\\Notepad++\notepad++");
                Console.WriteLine($"Started  a new process with ID {testproc.Id}");
                Console.WriteLine($"Get process by id {Process.GetProcessById(testproc.Id).ProcessName}");
                testproc.Kill();
                Console.WriteLine($"Process with Id {testproc.Id} was killed");
                Thread.Sleep(5000);
                try
                {
                    Console.WriteLine($"Get process by id {Process.GetProcessById(testproc.Id).ProcessName}");
                }
                catch (Exception e) {
                    Console.WriteLine($"GetProcessById filed with Exception: {e.Message}");
                }
            }
        }
    }
    
    

    On .Net Core 2.1 and .net core 3.1 i received a next:

    Started  a new process with ID 9896
    Get process by id notepad++
    Process with Id 9896 was killed
    GetProcessById filed with Exception: Process has exited, so the requested information is not available.
    
    

    GetProcessByID works correctly with killed process in actual .net core version.

  10. KalleOlaviNiemitalo commented on Jun 6, 2020

    @KalleOlaviNiemitalo
    Started  a new process with ID 9896
    Get process by id notepad++
    Process with Id 9896 was killed
    GetProcessById filed with Exception: Process has exited, so the requested information is not available.
    

    That exception comes from Process.ProcessName, not Process.GetProcessById.

  11. KalleOlaviNiemitalo commented on Jun 7, 2020

    @KalleOlaviNiemitalo

    So I think it is Windows behavior.

    It is Windows behavior that OpenProcess can open a process that has already terminated. Process.GetProcessById tries to detect that situation and throw ArgumentException, but the detection no longer works in .NET Core.

    A PowerShell script that uses Get-Process can work around the bug by checking Process.HasExited, which has the correct value. Alternatively, Get-Process could be changed to do that.

  12. ghost closed this as completedon Jun 8, 2020
  13. TishSerg commented on May 23, 2022

    @TishSerg

    Hi. I just stumbled upon this nasty behavior of PowerShell 7.2.3.
    And like in the case of topicstarter:

    On powershell 5.1 everything works fine

    OS: Microsoft Windows [Version 10.0.19044.1706]

  14. KalleOlaviNiemitalo commented on May 23, 2022

    @KalleOlaviNiemitalo

    dotnet/runtime#63937 was fixed in .NET v7.0.0-preview.3.22175.4. #17061 updated to .NET SDK 7.0.100-preview.4.22252.9. When PowerShell v7.3.0-preview.4 is released, it should include the fix.

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

    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aResolution-AnsweredThe question is answered.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions