Мне нужна помощь в обработке пакетных скриптов, помощь, потому что снова работаю с бортовыми инструментами, дополнительные компоненты не устанавливаются.

У меня есть сценарий CMD.exe, который собирает информацию о запущенных процессах (через tasklist.exe) и направляет их как в файл, каждой строке предшествует метка времени. Этот файл позже используется для генерации некоторых модных графиков для всех процессов, которые используют память или время процессора выше некоторого порога.

Но проблема в том, что мне нужно запустить этот скрипт из своего окружения прямо перед запуском loadtest, и мне нужно остановить его после завершения теста. Запуск и остановка не в одном процессе и могут быть довольно продолжительными (от нескольких минут до нескольких часов).

Я уже пытался использовать команду TITLE чтобы потом иметь возможность идентифицировать работающий скрипт, чтобы убить его с помощью TASKKILL /F /FI "WINDOWTITLE EQ PSMON" но это не работает, кажется, что заголовок окна не установлен, если скрипт не стартет мануал.

Для интересующихся вот сценарий:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
TITLE=PSMON

:START
SET FILE=%TEMP%\psmon.csv
ECHO TIMESTAMP^;IMAGENAME^;PID^;MEMKB^;CPUTIME>%FILE%

:LOOP
TITLE=PSMON
SET TS=%TIME%
SET SEK=%TS:~7,1%
IF %SEK% == 0 (
    FOR /F "tokens=1-12 delims=,:" %%A IN ('TASKLIST /V /NH /FO CSV') DO (
    SET IMAGE=%%A
    SET PID=%%B
    SET MEM=%%E
    SET CPUH=%%H
    SET CPUM=%%I
    SET CPUS=%%J
    SET /A CPU=!CPUH!*3600 + !CPUM!*60 + !CPUS!
    IF !CPU! GTR 100 (
        ECHO %DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%%TS:~0,2%%TS:~3,2%%TS:~6,2%^;!IMAGE:~1,-1!^;!PID:~1,-1!^;!MEM:~1,-3!^;!CPU!>>%FILE%
        )
    )
)
GOTO LOOP

И чтобы быть ясным, вопрос в том, как я могу идентифицировать экземпляр этого с помощью встроенных инструментов Windows и завершить процесс, если это не запускается непосредственно на cmdline или с помощью двойного щелчка (попробуйте запустить его вторым пакетом .cmd файл с помощью команды запуска).

Я хотел бы получить что-то вроде PID при запуске скрипта и записать его в временный файл или что-то вроде того, как это делается в Unix-системах, но я сомневаюсь, что есть что-то подобное.

РЕДАКТИРОВАТЬ: Получил намека на кучу строк кода, подобных этим:

for /f "usebackq tokens=2" %%a in (`tasklist /FO list /FI "SESSIONNAME eq %SESSIONNAME%" /FI "USERNAME eq %USERNAME%" /FI "WINDOWTITLE eq %instance%" ^| find /i "PID:"`) do set PID=%%a
if not defined PID for /f "usebackq tokens=2" %%a in (`tasklist /FO list /FI "SESSIONNAME eq %SESSIONNAME%" /FI "USERNAME eq %USERNAME%" /FI "WINDOWTITLE eq Administrator:  %instance%" ^| find /i "PID:"`) do set PID=%%a
if not defined PID echo !Error: Could not determine the Process ID of the current script.  Exiting.& exit /b 1

К сожалению, они просто не работают, скрипт всегда останавливается с определенным сообщением об ошибке. Может, стоит упомянуть, что я работаю на Win7?

1 ответ1

1

Хорошо, спасибо DavidPostill и этой ссылке. Что такое PID текущего cmd.exe, действительно есть рабочий способ получить PID с помощью встроенных инструментов.

SET T=%TEMP%\sthUnique.tmp
wmic process where (Name="WMIC.exe" AND CommandLine LIKE "%%%TIME%%%") get ParentProcessId /value | find "ParentProcessId" >%T%
SET /P PID=<%T%
ECHO %PID:~16%>%TEMP%\my.pid

После этого я смогу убить задачу позже.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .