it-swarm.com.de

Überprüfen Sie, ob ein Prozess ausgeführt wird, und stoppen Sie ihn

Wie kann ich auf korrekte Weise feststellen, ob ein Prozess ausgeführt wird, z. B. FireFox, und ihn stoppen?

Ich habe mich umgesehen und der beste Weg, den ich gefunden habe, war:

if((get-process "firefox" -ea SilentlyContinue) -eq $Null){ 
        echo "Not Running" 
}

else{ 
    echo "Running"
    Stop-Process -processname "firefox"
 }

Ist dies der ideale Weg, dies zu tun? Wenn nicht, was ist der richtige Weg?

33
user4350786

So wie Sie es tun, fragen Sie zweimal nach dem Prozess. Auch Lynn macht einen guten Punkt darüber, zuerst Nizza zu sein. Ich würde wahrscheinlich etwas wie das Folgende versuchen:

# get Firefox process
$firefox = Get-Process firefox -ErrorAction SilentlyContinue
if ($firefox) {
  # try gracefully first
  $firefox.CloseMainWindow()
  # kill after five seconds
  Sleep 5
  if (!$firefox.HasExited) {
    $firefox | Stop-Process -Force
  }
}
Remove-Variable firefox
63
Joey

Wenn Sie das exakte Ergebnis "running"/"not run" nicht anzeigen müssen, können Sie einfach:

ps notepad -ErrorAction SilentlyContinue | kill -PassThru

Wenn der Prozess nicht ausgeführt wurde, erhalten Sie keine Ergebnisse. Wenn es ausgeführt wurde, erhalten Sie eine get-process-Ausgabe und der Prozess wird gestoppt.

6
Adam Luniewski

@ jmp242 - Der generische System.Object-Typ enthält nicht die CloseMainWindow-Methode, aber das statische Casting des System.Diagnostics.Process-Typs, wenn die ProcessList-Variable gesammelt wird, funktioniert für mich. Der aktualisierte Code (von diese Antwort ) mit diesem Casting (und der Loop wurde geändert, um ForEach-Object zu verwenden) ist unten aufgeführt.

function Stop-Processes {
    param(
        [parameter(Mandatory=$true)] $processName,
                                     $timeout = 5
    )
    [System.Diagnostics.Process[]]$processList = Get-Process $processName -ErrorAction SilentlyContinue

    ForEach ($Process in $processList) {
        # Try gracefully first
        $Process.CloseMainWindow() | Out-Null
    }

    # Check the 'HasExited' property for each process
    for ($i = 0 ; $i -le $timeout; $i++) {
        $AllHaveExited = $True
        $processList | ForEach-Object {
            If (-NOT $_.HasExited) {
                $AllHaveExited = $False
            }                    
        }
        If ($AllHaveExited -eq $true){
            Return
        }
        Start-Sleep 1
    }
    # If graceful close has failed, loop through 'Stop-Process'
    $processList | ForEach-Object {
        If (Get-Process -ID $_.ID -ErrorAction SilentlyContinue) {
            Stop-Process -Id $_.ID -Force -Verbose
        }
    }
}
0
Kit

Danke @Joey. Es ist was ich suche.

Ich bringe nur einige Verbesserungen mit:

  • mehrere Prozesse berücksichtigen 
  • um zu vermeiden, dass das Zeitlimit erreicht wird, wenn alle Prozesse abgeschlossen sind 
  • das Ganze in einer Funktion verpacken

function Stop-Processes {
    param(
        [parameter(Mandatory=$true)] $processName,
                                     $timeout = 5
    )
    $processList = Get-Process $processName -ErrorAction SilentlyContinue
    if ($processList) {
        # Try gracefully first
        $processList.CloseMainWindow() | Out-Null

        # Wait until all processes have terminated or until timeout
        for ($i = 0 ; $i -le $timeout; $i ++){
            $AllHaveExited = $True
            $processList | % {
                $process = $_
                If (!$process.HasExited){
                    $AllHaveExited = $False
                }                    
            }
            If ($AllHaveExited){
                Return
            }
            sleep 1
        }
        # Else: kill
        $processList | Stop-Process -Force        
    }
}
0
smo