Как получить идентификатор процесса по имени своей службы с переменной script to variable
У меня есть служба с именем WinDefend
, и она выполняется в процессе svchost.exe
Там еще много процессов svchost.exe
, и мне нужно найти способ получить его идентификатор.
когда я запускаю tasklist /svc
, я вижу:
![enter image description here]()
Я не уверен, как это получить.
Я нашел эту команду, но когда я попробовал select "PID"
, она дала мне пустой столбец.
![enter image description here]()
Мне нужно, чтобы PID процесса был переменным.
Ответы
Ответ 1
tasklist
просто возвращает текст, а не фактические объекты, у которых есть свойства, к которым вы можете получить доступ. Вы можете использовать WMI для получения этой информации:
$id = Get-WmiObject -Class Win32_Service -Filter "Name LIKE 'WinDefend'" |
Select-Object -ExpandProperty ProcessId
$process = Get-Process -Id $id
Ответ 2
$p=Tasklist /svc /fi "SERVICES eq windefend" /fo csv | convertfrom-csv
$p.PID
Ответ 3
Раздражает, так как это требует, чтобы вы установили уникальный заголовок для 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 возвращает идентификатор процесса текущего процесса.
Ответ 4
Альтернативный способ получения PID процесса:
$serviceName = 'svchost.exe'
$pidArgumentPlacement = 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[$pidArgumentPlacement]
Или вы можете суммировать его до:
$servicePID = $($($(tasklist /v /fo csv | findstr /i $serviceName) -replace '["]') -split ",")[$pidArgumentPlacement]
Примечание.. Это захватит первую службу, которая соответствует вашему $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
.