Как получить идентификатор процесса по имени своей службы с переменной script to variable

У меня есть служба с именем WinDefend, и она выполняется в процессе svchost.exe Там еще много процессов svchost.exe, и мне нужно найти способ получить его идентификатор. когда я запускаю tasklist /svc, я вижу:

Я не уверен, как это получить. Я нашел эту команду, но когда я попробовал select "PID", она дала мне пустой столбец.

Мне нужно, чтобы PID процесса был переменным.

4 ответа

tasklist просто возвращает текст, а не фактические объекты, у которых есть свойства, к которым вы можете получить доступ. Вы можете использовать WMI для получения этой информации:

$id = Get-WmiObject -Class Win32_Service -Filter "Name LIKE 'WinDefend'" | 
 Select-Object -ExpandProperty ProcessId
$process = Get-Process -Id $id


$p=Tasklist /svc /fi "SERVICES eq windefend" /fo csv | convertfrom-csv
$p.PID


Раздражает, так как это требует, чтобы вы установили уникальный заголовок для script, если вы хотите pid для текущего процесса. Затем найдите этот уникальный заголовок в списке процессов. К счастью, команда Title позволяет вам сделать именно это. Также см. MagicAndi ответ...

Вот мое решение пакетного файла:

@ECHO OFF
:SetVars
 SET _Thread=%1
 title=ExecBatch_%_Thread%
 Set /A "_iPID=0"
:Main
 CALL :getPID _iPID %_Thread%
 ...
EXIT /b
::----------------
::---- GetPID ---- 
::----------------
:getPID 
 setlocal 
 set _getPIDcmd=tasklist /v /fo csv 
 for /f "tokens=2 delims=," %%i in ('%_getPIDcmd% ^| findstr /i "ExecBatch_%2"') do (
 echo %%~i
 set _pid=%%~i
 )
 endlocal & Set %~1=%_pid%
exit /b

Кстати, у меня было "удовольствие" делать это снова и снова с годами, через API, или пакет, или ps. Выберите свой яд - на платформе Windows все равно.

Я нашел еще лучший способ через powershell: $pid возвращает идентификатор процесса текущего процесса.


Альтернативный способ получения PID процесса:

$serviceName = 'svchost.exe'
$******************** = 1
# Call for the verbose version of tasklist and filter it for the line with your service name. 
$serviceAsCSVString = tasklist /v /fo csv | findstr /i $serviceName
# Remove the quotes from the CSV string
$serviceCSVStringWithoutQuotes = $serviceAsCSVString -replace '["]'
# Turn the string into an array by cutting at the comma
$serviceAsArray = $serviceCSVStringWithoutQuotes -split ","
# Get the pid from the array
$servicePID = $serviceAsArray[$********************]

Или вы можете суммировать его до:

$servicePID = $($($(tasklist /v /fo csv | findstr /i $serviceName) -replace '["]') -split ",")[$********************]

Примечание.. Это захватит первую службу, которая соответствует вашему $serviceName, если вы запустите службу, которая запускает несколько экземпляров самого себя (e.x. slack), вы получите только первый pid. tasklist /v /fi "IMAGENAME eq slack.exe" /fo csv возвращает массив с каждой строкой CSV, являющейся записью массива. Вы также можете отфильтровать это с помощью findstr, чтобы избежать получения имен столбцов.

EDIT: Поскольку WinDefend является подсервисом программы (в этом случае svchost.exe) вам может потребоваться заменить флаг verbose для tasklist на /svc следующим образом:

$serviceAsCSVString = tasklist /svc /fo csv | findstr /i $serviceName

альтернативно искать имя службы через фильтр:

$serviceAsCSVString = tasklist /svc /fi "SERVICES eq $serviceName" /fo csv | findstr /i $serviceName

И принимая во внимание, что фильтр возвращает строку имен столбцов, а также строку, которую вы искали:

$serviceCSVStringWithoutQuotes = $serviceAsCSVString[1] -replace '["]'

Предполагая, что вы изменили $serviceName на WinDefend вместо svchost.exe.

licensed under cc by-sa 3.0 with attribution.