Matar um processo em lote e relatar o sucesso
-
19-09-2019 - |
Pergunta
Eu tenho o seguinte arquivo em lote, que encerra o programa iTunes, para que, se eu conectar meu iPod, ele não será sincronizado. (Eu sei que você pode configurar isso no iTunes.)
@echo off
:kill
cls
taskkill /F /IM itunes.exe >nul
if %errorlevel%==1 {
echo iTunes not found.
} else {
echo iTunes is killed.
}
goto kill
No entanto, o >nul
não responde ao comando; Portanto, apenas fornece o texto do comando padrão. Então, sim, o que eu quero fazer:
Se o iTunes não for encontrado, conforme dado pelo comando, ele deve exibir
iTunes não encontrados
Se for encontrado e encerrado,
O iTunes é morto
Ajuda? O ErrorLevel não funciona, isso parece ser culpa do nul
não está funcionando.
Solução
Funciona para mim pelo menos:
> taskkill /f /im powershell.exe && echo worked || echo not worked SUCCESS: The process "powershell.exe" with PID 3228 has been terminated. worked > taskkill /f /im powershell.exe && echo worked || echo not worked ERROR: The process "powershell.exe" not found. not worked
Então taskkill
é retornando um código de saída adequado. O redirecionamento de sua saída não tem nada a ver com isso. Mas o nível de erro para falha é 128. Você realmente deve usar o idioma adequado para verificar erros.
Também parece que taskkill
está imprimindo stderr
Então você vê sua saída ainda, quando apenas redirecionando stdout
. Você pode considerar reescrever o código acima para:
taskkill /F /IM itunes.exe >nul 2>&1
if errorlevel 1 (echo iTunes not found.) else (echo iTunes is killed.)
o 2>&1
Redireciona a saída de erro padrão para o vasto nada. if errorlevel 1
Verificações para errorlevel
ser pelo menos 1 que deve funcionar neste ponto:
Número do Nível de Erro Especifica uma condição verdadeira se a última execução do programa retornar um código de saída igual ou maior que o número especificado. -
help if
Geralmente verificando errorlevel
com if %errorlevel%==
é uma ideia muito ruim, a menos que você esteja comparando com 0. a semântica para códigos de saída são que anything
falha diferente de sinais de zero. Sua suposição aqui apenas foi que taskkill
retornaria 1
na falha.
Respos, posso perguntar por que você está fazendo isso em um loop sem fim? taskkill
já mata tudo instâncias de itunes.exe
. E você está executando um loop apertado sem atrasos, então seus arquivos em lote provavelmente consomem um núcleo da CPU enquanto estiver em execução.
ETA: Esquecido sua edição: Por que aparelho de mão encaracolada? Os blocos nos arquivos em lote são delimiados por parênteses redondos.
Outras dicas
Uma solução alternativa, no VBScript, salve abaixo o código como mykill.vbs
Set objArgs = WScript.Arguments
strProcess = objArgs(0)
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process Where Name ='" & strProcess & "'")
If colProcesses.Count = 0 Then
Wscript.Echo strProcess & " is not running."
Else
Wscript.Echo strProcess & " is running."
'Kill the process
For Each objProcess in colProcesses
r=objProcess.Terminate()
WScript.Echo "r is " & r
If r = 0 Then
WScript.Echo strProcess & " killed"
End If
Next
End If
na linha de comando
c:\test> cscript //nologo mykill.vbs "itunes.exe"
Por que você não usa o PowerShell?
try
{
Stop-Process -Name itunes -ErrorAction Stop
"iTunes is killed"
}
catch
{
"iTunes not found"
}