在批处理中杀死一个进程并报告成功

我有以下batch file,终止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 

但是,这个命令没有回应。 所以它只是给出了默认的命令文本。 所以是的,我想要做什么:

如果找不到iTunes,则应显示该命令

未findiTunes

如果发现并终止,

iTunes被杀害

帮帮我? 错误级别不起作用,这似乎是没有工作的错误。

至少适用于我:

  > taskkill / f / im powershell.exe && echo工作|| 回声没有工作
成功:具有PID 3228的进程“powershell.exe”已终止。
工作

 > 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

通常,使用if %errorlevel%==来检查错误errorlevel是一个非常糟糕的主意,除非您将其与0进行比较。退出代码的语义是anything非零信号失败。 你在这里的假设就是taskkill在失败时会返回1

我可以问你为什么这样做是无止境的? taskkill已经杀死了itunes.exe 所有实例。 而且你在没有任何延迟的情况下运行在一个紧密的循环中,所以你的批处理文件在运行时可能会消耗一个CPU核心。

ETA:忽略了你的编辑:为什么地球上花括号? 批处理文件中的块由圆括号分隔。

一个替代的解决方案,在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" 

你为什么不使用PowerShell?

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