批处理错误“(意外),如果语句嵌套在for循环中

时间:2019-08-31 19:01:58

标签: windows batch-file for-loop if-statement

我写了这个小脚本,每当窗口标题为“广告”时杀死Spotify。现在,它仅查找spotify.exe进程,如果窗口名称匹配,则将其杀死(下一步是每秒执行一次)。但是,每次执行该错误都会告诉我(中有一个意外的IF /i "%A:~0,4" (,但是这样的语句不在我的代码中:好像Windows修改了IF /i "%%A:~0,4%"=="PID:" (之前执行它。

这是脚本:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

tasklist /fi "imagename eq spotify.exe" /fo list /v > tmp.txt

FOR /F "usebackq tokens=*" %%A IN ("tmp.txt") DO (
  SET test=%%A
  echo %%A
  IF /i "%%A:~0,4%"=="PID:" (
    SET "pid=%%A:PID:          =%"
    echo %pid%
  )
  IF /i "%%A:~0,13%"=="Window Title:" (
    SET "wintitle=%%A:Window Title: =%"
    echo %wintitle%
  )
  IF "%wintitle%"=="Advertisement" (
    taskkill /F /PID %pid%
  )
)

PAUSE

错误消息(启用echo):

C:\Users\marco\Desktop>antispotify.bat

C:\Users\marco\Desktop>tasklist /fi "imagename eq spotify.exe" /fo list /v  1>tmp.txt
( was unexpected at this time.
C:\Users\marco\Desktop>  IF /i "%A:~0,4" (

有人知道我的代码有什么问题吗?

2 个答案:

答案 0 :(得分:1)

如注释中所述,子字符串操作不适用于for变量(%%a类型)。相反,您需要一个普通变量,当然需要delayed expansion

但是我可以建议另一种方法:

@ECHO OFF
SETLOCAL 
for /f "tokens=2,9 delims=," %%a in ('tasklist /fi "imagename eq notepad.exe" /fo csv /v /nh') do (
   set "pid=%%~a"
   set "wintitle=%%~b"
)
set pid
set wintitle
IF "%wintitle%"=="Advertisement" taskkill /F /PID %pid%

在这里,我们直接在for循环中使用命令,而不是使用临时文件。除此之外,我们将输出格式更改为csv(更易于解析),而没有标题行(/nh

(我使用notepad.exe,因为我没有Spotify,但是很容易适应)

答案 1 :(得分:1)

通过使用以下批处理文件而不使用delayed expansion,也可以完成强制杀死广告运行中的Spotify进程的任务。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=1* delims=:" %%I in ('%SystemRoot%\System32\tasklist.exe /FI "imagename eq spotify.exe" /FO LIST /V 2^>nul') do (
    if /I "%%~I" == "PID" (
        for /F %%K in ("%%~J") do set "ProcessIdentifier=%%~K"
    ) else if /I "%%~I" == "Window Title" (
        for /F "tokens=*" %%K in ("%%~J") do if /I "%%~K" == "Advertisement" call %SystemRoot%\System32\taskkill.exe /F /PID %%ProcessIdentifier%%
    )
)
endlocal

使用延迟的环境变量扩展的相同代码:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "tokens=1* delims=:" %%I in ('%SystemRoot%\System32\tasklist.exe /FI "imagename eq spotify.exe" /FO LIST /V 2^>nul') do (
    if /I "%%~I" == "PID" (
        for /F %%K in ("%%~J") do set "ProcessIdentifier=%%~K"
    ) else if /I "%%~I" == "Window Title" (
        for /F "tokens=*" %%K in ("%%~J") do if /I "%%~K" == "Advertisement" %SystemRoot%\System32\taskkill.exe /F /PID !ProcessIdentifier!
    )
)
endlocal

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • call /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • setlocal /?
  • taskkill /?
  • tasklist /?

另请参阅:How does the Windows Command Interpreter (CMD.EXE) parse scripts?