Quelle est la bonne façon de déterminer si un processus est en cours d'exécution, par exemple FireFox, et de l'arrêter?
J'ai fait quelques recherches et le meilleur moyen que j'ai trouvé était le suivant:
if((get-process "firefox" -ea SilentlyContinue) -eq $Null){
echo "Not Running"
}
else{
echo "Running"
Stop-Process -processname "firefox"
}
Est-ce la manière idéale de le faire? Si non, quelle est la bonne façon de le faire?
La façon dont vous le faites vous interroge deux fois sur le processus. Lynn soulève également un point positif à propos de Nice. J'essaierais probablement quelque chose comme ce qui suit:
# 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
Si vous n'avez pas besoin d'afficher le résultat exact "running"/"not runnuning", vous pouvez simplement:
ps notepad -ErrorAction SilentlyContinue | kill -PassThru
Si le processus ne fonctionnait pas, vous n'obtiendrez aucun résultat. S'il était en cours d'exécution, vous recevrez le résultat get-process
et le processus sera arrêté.
@ jmp242 - le type générique System.Object
ne contient pas la méthode CloseMainWindow
, mais la conversion statique du type System.Diagnostics.Process
lors de la collecte de la variable ProcessList
fonctionne pour moi. Le code mis à jour (de cette réponse ) avec cette diffusion (et la boucle changée pour utiliser ForEach-Object
) se trouve ci-dessous.
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
}
}
}
Merci @ Joey. C'est ce que je cherche.
Je viens d'apporter quelques améliorations:
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
}
}