批处理程序:检查进程是否存在

37

我希望有一份批处理程序,它可以检查进程notepad.exe是否存在。

如果notepad.exe存在,则结束该进程,

否则,批处理程序将关闭自身。

以下是我已经完成的内容:

@echo off
tasklist /fi "imagename eq notepad.exe" > nul
if errorlevel 1 taskkill /f /im "notepad.exe"
exit

但是它不起作用。我的代码有什么问题?


1
为什么不在验证任务是否存在之后再调用 taskkill 呢? - Andriy M
3
对我来说,taskkill 没有改变错误级别... - user2033427
@Andriy M 我想要检查进程是否存在,然后结束该进程或关闭自身。 - user2176930
你的脚本似乎无论是否找到并杀死图像,都会自动关闭。 - Andriy M
2
可能是重复的问题:如何通过批处理脚本检查进程是否正在运行 - phuclv
5个回答

63

TASKLIST不会设置错误级别。

echo off
tasklist /fi "imagename eq notepad.exe" |find ":" > nul
if errorlevel 1 taskkill /f /im "notepad.exe"
exit

如果任务未找到,则TASKLIST输出中才会出现“:”,因此FIND将为not found设置错误级别为0,对于found则为1,这应该能够完成工作。

尽管如此,

taskkill /f /im "notepad.exe"

如果存在记事本任务,则将其杀死 - 如果不存在记事本任务,则不需要进行任何操作,因此您实际上不需要测试 - 除非有其他您想要执行的操作...比如也许

echo off
tasklist /fi "imagename eq notepad.exe" |find ":" > nul
if errorlevel 1 taskkill /f /im "notepad.exe"&exit

似乎可以按照您的要求执行-如果存在记事本进程,则终止该进程,然后退出-否则继续进行批处理


5
不必使用 if errorlevel,可以通过条件执行来进一步简化。 - rojo
4
也许最好是查找“notepad.exe”,因为输出已经被翻译了,我们无法确定“:”是否出现在所有语言中。 - Thomas Weller

27

这是一个一行代码解决方案

它只会在进程实际运行时运行taskkill,否则它将仅提供未运行的信息。

tasklist | find /i "notepad.exe" && taskkill /im notepad.exe /F || echo process "notepad.exe" not running.

如果进程正在运行,这是输出结果:

notepad.exe           1960 Console                   0    112,260 K
SUCCESS: The process "notepad.exe" with PID 1960 has been terminated.

如果未运行,则会输出以下内容:

process "notepad.exe" not running.

1
对我来说,在Windows 10上它可以工作,我在多个脚本中使用它。 - nicovota
也许我漏掉了什么。 - Arslan Ahmad khan
如果进程没有运行,错误级别仍然为0,这也很好。 - js2010
不是这样的,因为批处理文件会继续执行。如果您想让它一直循环“观察”进程是否结束(或存在),那该怎么办呢?这很复杂! - bat_cmd

13

TASKLIST无法设置一个你可以在批处理文件中检查的退出代码。检查退出代码的一个解决方法可能是解析其标准输出(它目前被重定向到NUL)。显然,如果找到了进程,TASKLIST将显示其详细信息,包括图像名称。因此,你可以使用FINDFINDSTR来检查TASKLIST的输出是否包含你在请求中指定的名称。如果搜索失败,FINDFINDSTR都会设置一个非空退出代码。所以,这将有效:

@echo off
tasklist /fi "imagename eq notepad.exe" | find /i "notepad.exe" > nul
if not errorlevel 1 (taskkill /f /im "notepad.exe") else (
  specific commands to perform if the process was not found
)
exit

还有一种不需要使用 TASKLIST 的替代方法。与 TASKLIST 不同的是,TASKKILL 确实设置了一个退出代码。特别是,如果它无法终止进程,因为进程根本不存在,它将设置退出代码 128。您可以检查该代码以执行您可能需要在指定进程不存在的情况下执行的特定操作:

@echo off
taskkill /f /im "notepad.exe" > nul
if errorlevel 128 (
  specific commands to perform if the process
  was not terminated because it was not found
)
exit

我发现如果图像名称包括文件扩展名超过25个字符,则任务列表输出中的“图像名称”列将被截断,这使得带有图像名称的“查找”命令无法正常工作。然而,仅通过“:”字符进行检测似乎太宽松了,我担心它可能会在未来版本的正面输出中发生。有没有其他更好的方法呢? - Elliott
1
@Elliott:如果你将可执行文件的名称存储在一个变量中,那么你可以在tasklist中使用整个值,在find中只使用前25个字符:tasklist /fi "imagename eq %imgname%" | find /i "%imgname:~0,25%" > nul - Andriy M
如果您使用 /F 参数,taskkill 命令才会更改其退出代码。我刚测试了一下,使用 taskkill 命令终止一个挂起的进程但没有加上 /f 参数,结果显示“SUCCESS: Sent termination signal to the process with PID 30564”,而退出代码始终为0。此情况出现在 win7 64 系统中。 - Badr Elmers
@BadrElmers:该消息表明taskkill以退出代码0结束(因为它是成功的)。如果在发送终止信号给进程时出现问题,则退出代码将不同。特别地,尝试在不存在的进程上使用没有/f选项的taskkill并检查退出代码。在我的情况下,退出代码仍满足“if errorlevel 128”条件(Win7 x64)。 - Andriy M

3
这就是为什么它不起作用,因为你编写的代码有问题,这就是为什么它总是退出并且脚本执行器会将其视为不可操作的批处理文件,从而阻止它退出和停止。所以必须修改代码。
tasklist /fi "IMAGENAME eq Notepad.exe" 2>NUL | find /I /N "Notepad.exe">NUL
if "%ERRORLEVEL%"=="0" (
msg * Program is running
goto Exit
)
else if "%ERRORLEVEL%"=="1" (
msg * Program is not running
goto Exit
)

相比于
@echo off
tasklist /fi "imagename eq notepad.exe" > nul
if errorlevel 1 taskkill /f /im "notepad.exe"
exit

-3

试试这个:

@echo off
set run=
tasklist /fi "imagename eq notepad.exe" | find ":" > nul
if errorlevel 1 set run=yes
if "%run%"=="yes" echo notepad is running
if "%run%"=="" echo notepad is not running
pause

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接