cara mendapatkan proses pid sendiri dari command prompt di windows

26

Saya mencoba menemukan cara untuk mendapatkan PID saya sendiri dari command prompt (untuk digunakan nanti dalam skrip kelelawar) sejauh ini satu-satunya cara berguna yang saya temukan adalah menggunakan getpids.exe dari sini: http://www.scheibli.com/ proyek / getpids / index.html tetapi saya sedang mencari perintah yang "built in" ke windows

sunting: saya sedang mencari cara "bukti peluru" - tidak ada asumsi tentang proses saya menjadi satu-satunya cmd.exe atau apa pun

radai
sumber

Jawaban:

36

Karena tidak ada solusi lain yang anti peluru dan bawaan, saya pikir saya akan menawarkan solusi berikut, tetapi perhatikan bahwa Anda harus menguraikan / menyimpan hasilnya, entah bagaimana:

title mycmd
tasklist /v /fo csv | findstr /i "mycmd"
tony roth
sumber
itu sangat rapi. Saya cukup yakin waktu saat ini + beberapa nomor yang dihasilkan secara acak dapat ditetapkan sebagai judul untuk mendekati antipeluru
radai
3
Jangan gunakan% acak% +% waktu% jika Anda memiliki scheduler, panggil skrip batch Anda dua kali secara bersamaan. Saya memiliki masalah bahwa skrip yang sama dipanggil dengan parameter berbeda pada saat yang sama. Benih untuk acak adalah sama dan saya mengalami tabrakan ketika membuat direktori sementara. Tidak ada jalan lain untuk menangani kesalahan saat membuat direktori sementara. Singkatnya, jika Anda dapat berasumsi bahwa skrip Anda tidak dipecat dua kali pada saat yang sama, trik ini akan berhasil.
Peter Schuetze
Mungkin (tidak diuji secara mendalam) yang mendapatkan stempel waktu yang lebih tepat (termasuk microseconds, daripada 1/100 detik seperti dalam% waktu%), akan lebih dapat diandalkan dalam kasus ini: wmic os get LocalDateTime(YearMonthDayHourMinuteSecond.Microsecond + Timezone). Kecuali jika penjadwal dapat menjalankan dua hal dalam mikrodetik yang sama persis ...
Gauthier Boaglio
Ini tidak akan berfungsi jika proses sedang berjalan di sesi lain di komputer karena judulnya ditampilkan sebagai Tidak Ada
FrinkTheBrave
Ini memberikan PID dari proses induk.
access_granted
7

Saya percaya yang berikut ini anti peluru, asalkan pengguna memiliki akses ke WMIC dan TEMP menunjuk ke jalur yang valid di mana pengguna memiliki hak istimewa menulis. Ini adalah hasil akhir dari beberapa karya kolaboratif di 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

Script membuat kunci eksklusif pada file sementara yang menggabungkan waktu saat ini ke dalam nama. Hanya akan ada tabrakan jika dua proses batch bernama mencoba untuk mendapatkan PID dalam interval waktu 0,01 detik yang sama, dalam hal ini hanya satu yang akan berhasil.

Setiap proses yang gagal akan berulang kali berulang kembali dan coba lagi dengan jalur file kunci baru sampai berhasil.

Path lengkap ke file kunci diubah menjadi ID unik yang dapat digunakan dalam permintaan WMIC. WMIC dijalankan dalam perintah FOR / F, yang berarti itu berjalan dalam proses cmd.exe anak. Itu sebabnya ParentProcessID dari proses cmd.exe diambil.

dbenham
sumber
7

Memperluas jawaban Tony Roth:

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

Menggunakan filter WINDOWTITLE menghindari pipa sehingga Anda bisa meletakkannya dalam for loop dan menetapkannya ke variabel dengan SET jika Anda suka:

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

Menghapus /vmembuatnya lebih cepat, dan /NHmenghilangkan garis tajuk. Anda memerlukan wildcard setelah "uniqueTitle"karena judul jendela sebenarnya berisi perintah saat ini (sehingga akan terus berlanjut jika Anda mencoba untuk mencocokkannya sepenuhnya).

David
sumber
6

Menggunakan PowerShell + WMI:

powershell (Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId
Nicolas Melay
sumber
Bagus; jika Anda memiliki PowerShell Core , itu menjadi lebih mudah (meskipun tidak ada perintah yang akan cepat ):pwsh -noprofile -c "(Get-Process -Id $PID).Parent.Id"
mklement
5
  1. Windows Task Manager, Anda harus pergi ke Lihat -> Pilih Kolom .. dan pilih PID.
  2. "tasklist / v" untuk mendapatkan informasi tugas verbose di command prompt.
  3. Process Explorer dari live.sysinternals.com .
Vivek Kumbhar
sumber
2
@Vivek, dari prompt perintah ... dan Anda membohongi jawaban
WooYek
saya hanya memberikan semua opsi yang mungkin .. dan tidak ada duplikasi .. saya bisa juga menyebutkan PowerShell tetapi saya menahan diri karena itu tidak datang secara default di XP dan 2003. Jika ini untuk Vista dan seterusnya OS, Ya PowerShell akan menjadi preferensi saya .
Vivek Kumbhar
5

jika Anda tahu hanya ada satu cmd.exe yang berjalan, Anda bisa mendapatkan PID dengan cara ini:

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

echo %pid%
zumalifeguard
sumber
Kedengarannya seperti asumsi yang mustahil, kode Anda mungkin tidak jelas
Raúl Salinas-Monteagudo
Raul, aku mengerti apa yang kamu katakan. Ini tidak aman dalam banyak kasus, tetapi aman di beberapa - seperti sistem kios atau VM di mana Anda berada dalam kendali penuh atas proses apa yang dimulai dan tidak
zumalifeguard
4

Ini harus melakukan trik:

daftar tugas / v

WooYek
sumber
3

Jika Anda ingin menemukan PID dari imagename "notepad.exe", maka kode berikut akan bekerja untuk Anda:

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

Jika Anda punya Windows 2003 Resource kit dorong melalui qgrep untuk mendapatkan garis yang Anda inginkan. Anda kemudian dapat mengekstrak pid dari sini (ini mengasumsikan Anda hanya menjalankan satu cmd sekaligus),

tasklist /v | qgrep cmd

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

Lihatlah trik batch kecil ini . Ini menetapkan judul cmd ke nilai khusus kemudian menggunakan daftar tugas untuk menemukannya. Inventif

\\ Greg

uSlackr
sumber
0

CARA PENDEK INI UNTUK MENDAPATKAN ID PROSES UNTUK CMD TERBUKA

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

Jawaban ini HANYA akan memberi Anda ID proses, dan tidak ada hal tambahan yang termasuk dalam jawaban teratas.

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%

Penjelasan:

-ada tidak akan menjadi PID untuk cmd.exe yang lebih besar dari 18100 jadi periksa apakah PID2 lebih besar dari 8100 jadi kita tahu apakah itu angka 4 digit atau 5 digit

kasus 1: PID 5 digit seperti 17504 memiliki PID1 val 17504 dan PID2 val 1750, jadi kami menggunakan PID1

kasus 2: PID 4 digit seperti 8205 memiliki nilai PID1 8205 "dan nilai PID2 8205, jadi kami menggunakan PID2

kasus 3: PID 4 digit seperti 4352 memiliki val PID1 4352 "dan val PID2 4352, jadi kami menggunakan PID2

Collin Fox
sumber