Пакет: проверка PID каждую секунду

Мне нужно проверить, какой PID, например, «notebook.exe», если этот процесс запущен в списке задач, поэтому мне нужно проверять это каждую секунду:

Если я запускаю это во время работы программы, работает:

echo off
cls
SETLOCAL EnableExtensions
SETLOCAL EnableDelayedExpansion


    for /f "TOKENS=1" %%a in ('wmic PROCESS where "Name='notebook.exe'" get ProcessID ^| findstr [0-9]') do set MyPID=%%a   
        @echo %USERNAME%-%COMPUTERNAME%-%MyPID%

Но мне нужно проверять это каждую секунду. То же самое, но в цикле, но не работает (переменная MyPID пуста)

echo off
cls
SETLOCAL EnableExtensions
SETLOCAL EnableDelayedExpansion

for /L %%n in (1,0,10) do (
    for /f "TOKENS=1" %%a in ('wmic PROCESS where "Name='notebook.exe'" get ProcessID ^| findstr [0-9]') do set MyPID=%%a   
        @echo %USERNAME%-%COMPUTERNAME%-%MyPID%
)

Является ли это возможным?


person csotelo    schedule 28.04.2017    source источник


Ответы (2)


Вы пытаетесь использовать переменную, которую вы установили внутри цикла for. Поскольку пакет выполняется построчно, а блоки кода (например, циклы) считаются за одну строку, это не сработает, потому что пакет сначала расширит %MyPID% до любого значения, а затем выполнит весь цикл for.

Вы приблизились к тому, чтобы исправить это. Использование Enable DelayedExpansion является частью трюка. но вам также нужно использовать ! вокруг переменных внутри цикла, чтобы пометить их как отложенные.

Итак, в заключение, это должно работать:

@echo off
cls
SETLOCAL EnableExtensions
SETLOCAL EnableDelayedExpansion

for /L %%n in (1,0,10) do (
    for /f "TOKENS=1" %%a in ('wmic PROCESS where "Name='notebook.exe'" get ProcessID ^| findstr [0-9]') do set MyPID=%%a   
        echo %USERNAME%-%COMPUTERNAME%-!MyPID!
)

Однако обратите внимание, что циклы в пакетном режиме намного проще сделать с помощью меток, так что это тоже будет работать, устраняя необходимость в отложенном расширении:

@echo off
cls
SETLOCAL EnableExtensions

:loop

for /f "TOKENS=1" %%a in ('wmic PROCESS where "Name='notebook.exe'" get ProcessID ^| findstr [0-9]') do set MyPID=%%a   
echo %USERNAME%-%COMPUTERNAME%-%MyPID%
timeout /t 1 /nobreak >nul

goto :loop

timeout /t 1 также гарантирует, что он ждет 1 секунду, прежде чем вернуться к :loop

person Dennis van Gils    schedule 28.04.2017

Это лучше сделать в PowerShell:

while ($true) {
    Start-Sleep -Seconds 1
    "{0}-{1}-{2}" -f $env:UserName,$env.ComputerName,(Get-Process -Name "Notebook.exe").id
}
person Jeff Zeitlin    schedule 28.04.2017