фильтр в tasklist.exe не принимает подстановочные знаки?

ОС: Windows XP, Windows 7 64-битная.

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

tasklist.exe /FI "WINDOWTITLE eq UniqueIdentifier*"

Все это прекрасно работало в XP. Теперь введите Windows7 64-бит. Здесь, если основной сценарий .cmd или любое другое окно оболочки .cmd пытается установить заголовок окна через

title UniqueIdentifier Followed By Descriptive Text

64-разрядная версия Windows7 любезно добавляет к заголовку другой текст (в частности, «Администратор:» или аналогичный). На предшествующий текст нельзя полагаться. Итак, теперь мы хотим использовать

tasklist.exe /FI "WINDOWTITLE eq *UniqueIdentifier*"

но ЭТО НЕ ПРОДАЕТСЯ с сообщением об ошибке "Поисковой фильтр не может быть распознан". Идти по пути использования нашего UniqueIdentifier в качестве постфикса не получится: команда

tasklist.exe /FI "WINDOWTITLE eq *UniqueIdentifier"

также приводит к тому же сообщению об ошибке. Кажется, что понятие Microsoft «подстановочный знак» в фильтре не выходит за рамки наличия «*» в качестве конечного символа. Ой.

У КОГО-ТО ЕСТЬ КАКИЕ-ЛИБО РЕШЕНИЯ? Pslist, похоже, не позволяет фильтровать по заголовку окна.


person David I. McIntosh    schedule 31.07.2012    source источник


Ответы (5)


Вы можете использовать параметр /V, чтобы включить заголовок окна в вывод, а затем передать результат в FIND (или FINDSTR) для фильтрации результата.

tasklist /v | find "UniqueIdentifier"
tasklist /v | findstr /c:"UniqueIdentifier"

Если вы используете FINDSTR, я рекомендую использовать параметр /C, чтобы вы могли включать пробелы в строку поиска.

Вы можете использовать опцию /I, если вам нужно выполнить поиск без учета регистра.

person dbenham    schedule 31.07.2012
comment
Да, это сработает, спасибо (скорее всего, я буду использовать grep вместо find или findstr, так как тогда я смогу использовать регулярное выражение). Однако я не сказал, что следующим шагом будет использование taskkill для уничтожения проблемных задач, и здесь у меня та же проблема. В качестве уродливого обходного пути я могу проанализировать вывод из tasklist /v | grep ..., а затем передать обратно в taskkill, но это очень уродливо. Я надеялся, что какой-то недокументированный способ заставить фильтр работать правильно. Вздох. Но спасибо, ваша идея сработает. - person David I. McIntosh; 01.08.2012
comment
FINDSTR имеет ограниченную поддержку регулярных выражений, но grep намного мощнее и надежнее. - person dbenham; 01.08.2012
comment
Многое согласовано. Как ни странно, в этом случае grep найдет строку, но, похоже, отбрасывает большую часть начала строки, что делает его бесполезным, поэтому findstr побеждает. Интересно, ставит ли список задач какие-то странные символы в середине строки???? (Кстати, в моем предыдущем комментарии то, как заставить фильтр работать, ссылалось на фильтрацию /FI в списке задач — фильтрация с помощью grep или findstr тривиальна.) - person David I. McIntosh; 01.08.2012
comment
Это не grep, который сбрасывает информацию. список задач извергает нечетные символы в stderr. Пайпинг 2›nul, как и в (tasklist -v 2>nul)|grep ..., работает нормально. Спасибо wmz за это наблюдение в другом вопросе. - person David I. McIntosh; 02.08.2012

Судя по моим экспериментам, подстановочный знак для taskkill работает только в конце строки, а не в какой-либо другой позиции. Я не могу найти никакой документации от Microsoft по этому поводу. Однако все примеры в документации следуют этому формату.

Successful:  notepad*
Fails: notepad*.exe
Fails *notepad*

Как уже упоминалось в другом ответе, лучше всего проанализировать вывод списка задач, чтобы получить именно то, что вы хотите, а не полагаться на довольно неправильное поведение taskkill.

person fiver    schedule 23.01.2019

Да, это работает нормально, если * находится в конце имени искомого процесса, как указывает пять.
Вот пример того, как запустить команду:

tasklist /FI "IMAGENAME eq no*"
person Henke    schedule 21.11.2020

Я думаю, что это работает в Windows 10. Вот мой фрагмент

set PROCNAME="Foobar"
tasklist /FI "IMAGENAME eq %PROCNAME%*" 2>NUL | find /I /N %PROCNAME%>NUL
if "%ERRORLEVEL%"=="0" (
    echo it is running
)

Обратите внимание на звездочку в фильтре.

person bviktor    schedule 03.01.2018

Используйте пауэршелл. Получить-Процесс. гораздо полезнее, если вы можете справиться с силой, которая есть. Пытаться

get-process | where MainWindowTitle -like "*UniqueIdentifier*" | select *
person Justin    schedule 23.03.2021