Завершение процесса в пакетном режиме и создание отчетов об успехе

У меня есть следующий пакетный файл, который завершает программу iTunes, поэтому, если я подключу свой iPod, он не будет синхронизировать его. (Я знаю, что вы можете настроить это в 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

Тем не менее >nul не отвечает на команду; так что это просто дает текст команды по умолчанию. Так что да, что я хочу сделать:

Если iTunes не найден, как указано в команде, он должен отобразить

iTunes не найден

Если он найден и прекращен,

iTunes убит

Помогите? уровень ошибки не работает, похоже, это вина nul не работает.

3 ответа

Решение

У меня работает как минимум:

 > taskkill /f /im powershell.exe && echo работал || эхо не сработало
УСПЕХ: Процесс "powershell.exe" с PID 3228 был прерван.
работал

> taskkill /f /im powershell.exe && echo работал || эхо не сработало
ОШИБКА: процесс "powershell.exe" не найден.
не работал 

Так taskkill возвращает правильный код выхода. Перенаправление его вывода не имеет к этому никакого отношения. Но уровень ошибок для отказа составляет 128. Вы действительно должны использовать правильную идиому для проверки на ошибки.

Также кажется, что taskkill печатает stderr так что вы видите его вывод еще, когда просто перенаправить stdout, Вы можете переписать код выше для:

taskkill /F /IM itunes.exe >nul 2>&1
if errorlevel 1 (echo iTunes not found.) else (echo iTunes is killed.)

2>&1 перенаправляет стандартный вывод ошибок в огромное ничто. if errorlevel 1 проверяет errorlevel будучи по крайней мере 1, который должен работать в этой точке:

ERRORLEVEL число Указывает истинное условие, если последний запуск программы возвратил код завершения, равный или больше указанного числа. - help if

Вообще проверка errorlevel с if %errorlevel%== это довольно плохая идея, если вы не сравниваете с 0. Семантика для кодов выхода такова, что anything сбой ненулевых сигналов. Ваше предположение здесь только что taskkill вернется 1 на провал.

Ответ, могу ли я любезно спросить, почему вы делаете это в бесконечном цикле? taskkill уже убивает все случаи itunes.exe, И вы работаете в узком цикле без каких-либо задержек, поэтому ваши пакетные файлы, вероятно, потребляют одно ядро ​​процессора во время работы.

ETA: упустил из виду ваши правки: зачем вообще фигурные скобки? Блоки в пакетных файлах разделяются круглыми скобками.

Почему вы не используете PowerShell?

try
{
    Stop-Process -Name itunes -ErrorAction Stop
    "iTunes is killed"
}
catch
{
    "iTunes not found"
}

Альтернативное решение, в VBScript, сохранить ниже код как 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

в командной строке

c:\test> cscript //nologo mykill.vbs "itunes.exe"
Другие вопросы по тегам