我找到了一个解决方案,它利用文本文件来跟踪 bat 文件具有的所有以前的 PID。它会尝试以静默方式杀死它们,然后将当前 PID 添加到列表中。
如果您不希望它杀死旧的、已经存在的进程,只需将具有“taskkill”的行替换为您想要对其执行的任何操作。
(可能需要您以管理员身份运行才能获得杀死重复进程的权限。如果您不想每次都以管理员身份运行,请参阅下面的权限提升代码以获取可选实现。)
@echo off
set WorkingDir=%cd%
if exist MostRecentPID.txt ( del "PIDinfo.txt" /f /q ) > nul
cd ..\..\..\..\..\..\..
title mycmd
tasklist /v /fo csv | findstr /i "mycmd" > %WorkingDir%\PIDinfo.txt
set /p PIDinfo=<%WorkingDir%\PIDinfo.txt
REM below, the 11 means get substring starting a position 11 with length of 5 characters. The tasklist command gives a long and verbose value so this will get just the PID part of the string.
set PID5chars=%PIDinfo:~11,5%
set PID4chars=%PIDinfo:~11,4%
if exist PreviousPIDs.txt (
for /F "tokens=*" %%A in (PreviousPIDs.txt) do taskkill.exe /F /T /PID %%A > nul 2>&1
goto CheckIfFourCharPID
)
:CheckIfFourCharPID
if %PID4chars% gtr 8100 (
for /F "tokens=*" %%A in (PreviousPIDs.txt) do taskkill.exe /F /T /PID %%A > nul 2>&1
echo %PID4chars% >> "PreviousPIDs.txt"
) else (
echo %PID5chars% >> "PreviousPIDs.txt"
)
解释:(警告:非常技术性)
-此解决方案获取 tasklist 命令的子字符串以仅获取 PID。cmd.exe 的 PID 不会大于 18100,因此请检查 PID4chars 是否大于 8100,以便我们知道它是 4 位数字还是 5 位数字
案例1:像17504这样的5位PID有一个PID5chars val 17504和一个PID4chars val 1750,所以我们将PID5chars添加到PIDs的文本文件中以杀死
案例 2:像 8205 这样的 4 位 PID 的 PID5chars val 为 8205" 和 PID4chars val 为 8205,所以我们将 PID4chars 添加到 PIDs 的文本文件中以杀死
案例3:像4352这样的4位PID,PID5chars val为4352",PID4chars val为4352,所以我们将PID4chars添加到PIDs的文本文件中以杀死
可选的许可海拔代码
(把它放在你的 bat 文件的顶部,它会以管理员身份自动运行它。)
@echo off
setlocal DisableDelayedExpansion
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
cd ..\..\..\..\..\..\..\..
if exist %cd%\Temp (
set temp=%cd%\Temp
goto vbsGetPrivileges
)
if exist %cd%\Windows\Temp (
set temp=%cd%\Windows\Temp
goto vbsGetPrivileges
)
set temp=%cd%
:vbsGetPrivileges
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:CheckIfRunningAsAdmin
net session >nul 2>&1
if %ERRORLEVEL% == 0 (
goto gotPrivileges
) else ( goto ElevatePermissions )
:ElevatePermissions
if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " " >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
"%SystemRoot%\System32\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & pushd .
cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1)
net session >nul 2>&1
if %ERRORLEVEL% == 0 (
goto Continue
) else (
REM unable to elevate permissions so tell user to run file as admin manually
echo Please re-run this file as administrator. Press any key to exit...
pause > nul
goto Exit
)
:Continue
<insert rest of code here>