2015-02-12 4 views
22

Каков правильный способ определения того, выполняется ли процесс, например FireFox, и его остановки?Как правильно проверить, запущен ли процесс и остановить его

Я сделал некоторые глядя вокруг, и лучший способ я нашел это:

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

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

Это идеальный способ сделать это? Если нет, то какой правильный способ сделать это?

+1

Имеет ли код к? –

+1

Да, но я хотел знать, является ли это идеальным способом сделать это? Их лучший способ? Есть ли у них какие-либо недостатки/преимущества в этом? –

+1

Я бы подумал, что более добрый способ сделать это - получить главный hwnd окна firefox и отправить его WM_CLOSE и/или WM_QUIT. Это может выходить за рамки того, на что способна сила. –

ответ

37

Как вы это делаете, вы дважды запрашиваете процесс. Также Линн поднимает хороший момент о том, чтобы быть хорошим первым. Я бы, наверное, попробовать что-то вроде следующего:

# 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 
+1

Charles - это ТОЧНО, что вам нужно. Обратите внимание, что Joey использует метод [CloseMainWindow()] (https://msdn.microsoft.com/en-us/library/system.diagnostics.process.closemainwindow%28v=vs.110%29.aspx). Прочтите документы на этой странице MSDN. Его сценарий пытается попросить приложение выйти красиво ... затем пытается убить. Очень приятно, Джо: +1. –

+0

Я как раз собирался сказать, это то, что я искал. –

+0

@CharlesWhitfield Да, я бы отметил это как ответ. И у вас уже есть. –

3

Если вам не нужно, чтобы отобразить точный результат «работы»/«не runnuning», вы могли бы просто:

ps notepad -ErrorAction SilentlyContinue | kill -PassThru 

Если процесс не работает, вы не получите никаких результатов. Если он был запущен, вы получите вывод get-process, и процесс будет остановлен.

+7

Для новичка, как я, полностью 'Get-Process notepad -ErrorAction SilentlyContinue | Stop-Process -PassThru' –

0

Спасибо @Joey. Это то, что я ищу.

Я просто принести некоторые улучшения:

  • принять во внимание несколько процессов
  • , чтобы избежать достижения тайм-аут, когда все процессы окончились
  • упаковать весь в функции

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

Одна из проблем заключается в том, что вы можете попасть в состояние, в котором вы получаете ОШИБКА: Ошибка вызова метода, потому что [System.Object []] не содержит метода с именем «CloseMainWindow». , но $ processList | Stop-Process -Force работает. Не знаете, как правильно обрабатывать эту ошибку. – jmp242

Смежные вопросы