Windows의 명령 프롬프트에서 자체 프로세스 pid를 얻는 방법


26

나는 명령 프롬프트에서 내 PID를 얻는 방법을 찾으려고 노력했다 . projects / getpids / index.html 하지만 Windows에 "내장 된"명령을 찾고 있습니다.

편집 : 메신저 "방탄 증명"방법을 찾고-내 프로세스에 대한 가정은 유일한 cmd.exe 또는 기타

답변:


36

다른 솔루션은 방탄 및 내장되어 있지 않으므로 다음 솔루션을 제공한다고 생각했지만 결과를 어떻게 든 구문 분석 / 저장해야합니다.

title mycmd
tasklist /v /fo csv | findstr /i "mycmd"

정말 깔끔합니다. im 현재 시간 + 무작위로 생성 된 숫자를 제목으로 설정하여 방탄에 가까워 질 수 있습니다.
radai

3
스케줄러가 배치 스크립트를 동시에 두 번 호출하는 경우 % random % + % time %를 사용하지 마십시오. 같은 스크립트가 다른 매개 변수로 동시에 호출되었다는 문제가있었습니다. 랜덤의 시드는 동일했고 임시 디렉토리를 만들 때 충돌이 발생했습니다. 임시 디렉토리를 만들 때 오류를 처리 할 방법이 없었습니다. 간단히 말해, 스크립트가 동시에 두 번 실행되지 않는다고 가정 할 수 있다면이 트릭이 효과적입니다.
피터 슈 체제

보다 정확한 타임 스탬프 ( microseconds% time %에서와 같이 1/100 초가 아닌 포함)를 얻는 것이 wmic os get LocalDateTime(YearMonthDayHourMinuteSecond.Microsecond + Timezone) 보다 더 안정적 일 수 있습니다 (심층 테스트되지 않음 ). 스케줄러가 정확히 동일한 마이크로 초에서 두 가지를 실행할 수 없다면 ...
Gauthier Boaglio

제목이 해당 없음으로 표시되어 프로세스가 컴퓨터의 다른 세션에서 실행중인 경우 작동하지 않습니다.
FrinkTheBrave

이것은 부모 프로세스의 PID를 제공합니다.
access_granted

7

사용자가 WMIC에 액세스 할 수 있고 TEMP가 사용자에게 쓰기 권한이있는 유효한 경로를 가리키는 경우 다음 사항이 방탄이라고 생각합니다. 이것은 http://www.dostips.com/forum/viewtopic.php?f=3&t=6133 에서 일부 공동 작업의 최종 결과입니다 .

@echo off

:getPID  [RtnVar]
::
:: Store the Process ID (PID) of the currently running script in environment variable RtnVar.
:: If called without any argument, then simply write the PID to stdout.
::
setlocal disableDelayedExpansion
:getLock
set "lock=%temp%\%~nx0.%time::=.%.lock"
set "uid=%lock:\=:b%"
set "uid=%uid:,=:c%"
set "uid=%uid:'=:q%"
set "uid=%uid:_=:u%"
setlocal enableDelayedExpansion
set "uid=!uid:%%=:p!"
endlocal & set "uid=%uid%"
2>nul ( 9>"%lock%" (
  for /f "skip=1" %%A in (
    'wmic process where "name='cmd.exe' and CommandLine like '%%<%uid%>%%'" get ParentProcessID'
  ) do for %%B in (%%A) do set "PID=%%B"
  (call )
))||goto :getLock
del "%lock%" 2>nul
endlocal & if "%~1" equ "" (echo(%PID%) else set "%~1=%PID%"
exit /b

스크립트는 현재 시간을 이름에 통합하는 임시 파일에 대한 독점 잠금을 설정합니다. 명명 된 배치 프로세스 2 개가 동일한 0.01 초 시간 간격 내에 PID를 가져 오려고 시도하는 경우 충돌이 발생할 수 있으며,이 경우 하나만 성공합니다.

실패한 프로세스는 반복적으로 루프백하고 성공할 때까지 새 잠금 파일 경로로 다시 시도합니다.

잠금 파일의 전체 경로는 WMIC 쿼리에서 사용할 수있는 고유 ID로 변환됩니다. WMIC는 FOR / F 명령 내에서 실행되므로 자식 cmd.exe 프로세스에서 실행됩니다. cmd.exe 프로세스의 ParentProcessID가 검색되는 이유입니다.


7

Tony Roth의 답변을 확장 :

title uniqueTitle
for /f "tokens=2 USEBACKQ" %f IN (`tasklist /NH /FI "WINDOWTITLE eq uniqueTitle*"`) Do echo %f

WINDOWTITLE 필터를 사용하면 파이프를 피할 수 있으므로 파이프를 for 루프에 넣고 원하는 경우 SET를 사용하여 변수에 할당 할 수 있습니다.

title uniqueTitle
for /f "tokens=2 USEBACKQ" %f IN (`tasklist /NH /FI "WINDOWTITLE eq uniqueTitle*"`) Do set ourPID=%f

를 제거하면 /v더 빨라지고 /NH헤더 행이 제거됩니다. "uniqueTitle"창 제목에 실제로 현재 명령이 포함되어 있기 때문에 와일드 카드가 필요합니다 (따라서 완전히 일치 시키려고하면 계속 진행됩니다).


6

PowerShell + WMI 사용 :

powershell (Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId

좋은; PowerShell Core 를 사용하는 경우 명령이 더 빠르 더라도 훨씬 쉬워집니다 .pwsh -noprofile -c "(Get-Process -Id $PID).Parent.Id"
mklement

5
  1. Windows 작업 관리자에서보기-> 열 선택으로 이동하여 PID를 선택해야합니다.
  2. "tasklist / v"명령 프롬프트에서 자세한 작업 정보를 가져옵니다.
  3. live.sysinternals.com의 프로세스 탐색기 .

2
명령 프롬프트에서 @Vivek ... 그리고 당신은 답변을
속이는

방금 모든 가능한 옵션을 제공했습니다. 중복은 없습니다 .. PowerShell도 언급 할 수 있었지만 XP와 2003에서는 기본적으로 제공되지 않으므로 스스로 제지했습니다. Vista 이후의 OS 인 경우 PowerShell .
Vivek Kumbhar

5

cmd.exe가 하나만 실행되고 있으면 PID를 다음과 같이 얻을 수 있습니다.

for /F "tokens=1,2" %%i in ('tasklist /FI "IMAGENAME eq cmd.exe" /fo table /nh') do set pid=%%j

echo %pid%

그것은 믿을 수없는 가정처럼 들리지만, 코드는 색다른 것일 수 있습니다
Raúl Salinas-Monteagudo

라울, 당신이 무슨 말을하는지 이해합니다. 많은 경우에 안전하지 않지만 키오스크 시스템이나 어떤 프로세스가 시작되는지 여부를 완전히 제어하는 ​​VM과 같은 일부 경우에는 안전합니다.
zumalifeguard

4

트릭을 수행해야합니다.

작업 목록 / v


3

imagename "notepad.exe"의 PID를 찾으려면 다음 코드가 적합합니다.

for /F "tokens=1,2" %i in ('tasklist') do (
 if "%i" equ "notepad.exe" (set x=%j)
)
echo %x%

2

Windows 2003 Resource Kit가 있으면 qgrep를 통해 원하는 줄을 얻으십시오. 그런 다음 여기에서 pid를 추출 할 수 있습니다 (한 번에 하나의 cmd 만 실행 중이라고 가정).

tasklist /v | qgrep cmd

cmd.exe 2040 RDP-Tcp#447 0 1,804 K Running MACHINE\Administrator  0:00:00 Command Prompt


0

이것은 열린 CMD의 프로세스 ID를 얻는 가장 빠른 방법입니다.

tasklist /v /fi "imagename EQ cmd.exe" /FO LIST | FIND "PID:"

0

이 답변은 프로세스 ID 만 제공하며 최상위 답변에 포함 된 추가 항목은 없습니다.

title mycmd
tasklist /v /fo csv | findstr /i "mycmd" > PIDinfo.txt

set /p PIDinfo=<PIDinfo.txt
set PID1=%PIDinfo:~11,5%
set PID2=%PIDinfo:~11,4%

if %PID2% gtr 8100 (
    set PID=%PID2%
) else (
    set PID=%PID1%
)

echo %PID%

설명:

-cmd.exe에는 18100보다 큰 PID가 없으므로 PID2가 8100보다 큰지 확인하여 4 자리 또는 5 자리 숫자인지 확인하십시오.

사례 1 : 17504와 같은 5 자리 PID는 PID1 val 17504와 PID2 val은 1750이므로 PID1을 사용합니다

사례 2 : 8205와 같은 4 자리 PID의 PID1 값은 8205 "이고 PID2 값은 8205이므로 PID2를 사용합니다

사례 3 : 4352와 같은 4 자리 PID의 PID1 값은 4352 "이고 PID2 값은 4352이므로 PID2를 사용합니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.