cmd taskkill работает с жестко заданным значением PID, но не с тем же значением, что и переменная - PullRequest
1 голос
/ 13 января 2020

Я сталкиваюсь со странной ситуацией в пакетном скрипте Windows, над которым я сейчас работаю.

В этом разделе я извлекаю PID родительского процесса, используя имя его дочернего процесса (% PROCESS_NAME%). Это работает хорошо, и я могу повторить PARENT_PID без проблем:

for /f "usebackq tokens=2 delims==" %%a in (`wmic process where ^(name^='%PROCESS_NAME%'^) get parentprocessid /value`) do (
        set PARENT_PID=%%a
    )

echo !PARENT_PID!

Результат показать ожидаемое значение:

16392


Проблема находится в следующей строке:

taskkill /f /t /pid !PARENT_PID!

Процесс не останавливается и скрипт показывает странный текст (я работаю во французской среде):

"est introuvable .sus "16392


Если я заменю! PARENT_PID! с жестко запрограммированным значением PID:

taskkill /f /t /pid 16392

Все работает нормально, родительский процесс и его дочерний элемент убиты.

Я пробовал много вещей, но не могу понять, в чем дело. Если у кого-то есть идея, мне интересно, спасибо!

Ответы [ 2 ]

3 голосов
/ 13 января 2020

Попробуйте так, и вы увидите проблему:

@echo off
setlocal enableDelayedExpansion
for /f "usebackq tokens=2 delims==" %%a in (`wmic process where "name='explorer.exe'" get parentprocessid /value`) do (
        set PARENT_PID=%%a
    )

echo -!PARENT_PID!-

WMI C выход устанавливает один дополнительный возврат каретки в конце. Здесь Вы можете найти обходной путь (с дополнительным для l oop):

@echo off
setlocal enableDelayedExpansion
for /f "usebackq tokens=2 delims==" %%a in (`wmic process where "name='explorer.exe'" get parentprocessid /value`) do (
        for /f "tokens=* delims=" %%# in ("%%~a") do set "PARENT_PID=%%#"
    )

echo -!PARENT_PID!-
1 голос
/ 13 января 2020

Я всегда пытался предотвратить возникновение проблемы, а не исправлять ее позже. По этой причине вот несколько альтернативных предложений по решению проблемы нежелательного перевода строки.

Если вы можете включить свойство до и после целевого свойства, (в данном случае ParentProcessID) и убедитесь, что эти свойства 'pre' и 'post' не будут иметь значение NULL, вы можете получить свое значение без проблемного возврата c.

Пример:

@Set "PPID="
@For /F "EOL=H Tokens=2" %%A In ('""%__AppDir__%wbem\WMIC.exe" Process Where Name="%PROCESS_NAME%" Get Handle,ParentProcessID,SessionID 2>NUL"')Do @Set "PPID=%%A"
@Set PPID 2>NUL
@Pause


В качестве альтернативы вы можете использовать /Format.

Пример:

@Set "PPID="
@For /F "Skip=1 Tokens=2 Delims=," %%A In ('""%__AppDir__%wbem\WMIC.exe" Process Where Name="%PROCESS_NAME%" Get ParentProcessID /Format:CSV 2>NUL"') Do @Set "PPID=%%A"
@Set PPID 2>NUL
@Pause

Примечание: В мне известна проблема, связанная с неправильным расположением необходимых файлов .xsl. Одним из исправлений является перемещение этих файлов в правильный каталог \Windows\System32\wbem. В качестве альтернативы найдите его местоположение и укажите его непосредственно в значении. На системах, которые я использовал, я нашел csv.xsl в \Windows\System32\wbem\en-US, чтобы вы могли использовать (с необходимыми настройками):

@Set "PPID="
@For /F "Skip=1 Tokens=2 Delims=," %%A In ('""%__AppDir__%wbem\WMIC.exe" Process Where Name="%PROCESS_NAME%" Get ParentProcessID /Format:"%__AppDir__%wbem\en-US\csv.xsl" 2>NUL"') Do @Set "PPID=%%A"
@Set PPID 2>NUL
@Pause
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...