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?
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
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.
@ 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
}
}
}
Danke @Joey. Es ist was ich suche.
Ich bringe nur einige Verbesserungen mit:
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
}
}