วิธีรับโพรเซสของตัวเองจากพรอมต์คำสั่งใน windows


26

ฉันกำลังพยายามหาวิธีที่จะได้รับ PID ของฉันเองจากพรอมต์คำสั่ง (เพื่อใช้ในภายหลังในสคริปต์ค้างคาว) จนถึงวิธีที่มีประโยชน์เพียงอย่างเดียวที่ฉันพบคือการใช้ getpids.exe จากที่นี่: http://www.scheibli.com/ โครงการ / getpids / index.htmlแต่ฉันกำลังมองหาคำสั่งที่ "สร้าง" ใน windows

แก้ไข: ฉันกำลังมองหาวิธี "กระสุนพิสูจน์" - ไม่มีข้อสันนิษฐานเกี่ยวกับกระบวนการของฉันเป็น cmd.exe เท่านั้นหรืออะไร

คำตอบ:


36

เนื่องจากไม่มีวิธีแก้ปัญหาอื่นที่สามารถกันกระสุนได้และติดตั้งในตัวฉันจึงคิดว่าฉันขอเสนอวิธีแก้ไขปัญหาต่อไปนี้ แต่โปรดทราบว่าคุณจะต้องแยกวิเคราะห์ / บันทึกผลลัพธ์อย่างใด:

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

นั่นมันเรียบร้อยจริงๆ ฉันค่อนข้างแน่ใจว่าเวลาปัจจุบัน + จำนวนที่สร้างแบบสุ่มบางอย่างสามารถตั้งค่าเป็นชื่อที่จะได้รับใกล้กระสุน
radai

3
อย่าใช้% random% +% เวลา% หากคุณมีตัวกำหนดตารางเวลาเรียกสคริปต์ชุดงานของคุณสองครั้งในเวลาเดียวกัน ฉันมีปัญหาที่สคริปต์เดียวกันถูกเรียกด้วยพารามิเตอร์ที่แตกต่างกันในเวลาเดียวกัน เมล็ดสำหรับการสุ่มนั้นเหมือนกันและฉันวิ่งชนกันเมื่อสร้างไดเรกทอรีชั่วคราว ไม่มีวิธีในการจัดการกับข้อผิดพลาดเมื่อสร้างไดเรกทอรีชั่วคราว เรื่องสั้นสั้น ๆ หากคุณสามารถสมมติว่าสคริปต์ของคุณไม่ถูกไล่ออกสองครั้งในเวลาเดียวกันเคล็ดลับนี้ควรใช้งานได้
Peter Schuetze

อาจเป็น (ไม่ผ่านการทดสอบอย่างลึก) ที่ได้รับการประทับเวลาที่แม่นยำยิ่งขึ้น (รวมถึงmicrosecondsแทนที่จะเป็น 1/100 วินาทีเช่นใน% เวลา%) จะเชื่อถือได้มากขึ้นในกรณีนี้: wmic os get LocalDateTime(YearMonthDayHourMinuteSecond.Microsecond + Timezone) เว้นแต่ตัวกำหนดตารางเวลาจะสามารถเรียกใช้สองสิ่งใน microsecond เดียวกันแน่นอน ...
Gauthier Boaglio

สิ่งนี้จะไม่ทำงานหากกระบวนการทำงานในเซสชั่นอื่นบนคอมพิวเตอร์เนื่องจากชื่อเรื่องนั้นแสดงเป็น N / A
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

สคริปต์สร้างการล็อคแบบเอกสิทธิ์เฉพาะบุคคลในไฟล์ชั่วคราวที่รวมเวลาปัจจุบันไว้ในชื่อ อาจมีการชนกันได้ถ้าสองอย่างเช่นกระบวนการแบทช์ที่มีชื่อพยายามที่จะได้รับ PID ภายในช่วงเวลา 0.01 วินาทีเดียวกันซึ่งในกรณีเดียวจะประสบความสำเร็จ

กระบวนการใด ๆ ที่ล้มเหลวจะวนซ้ำและลองอีกครั้งด้วยพา ธ ล็อกไฟล์ใหม่จนกว่าจะสำเร็จ

พา ธ แบบเต็มไปยังไฟล์ล็อกถูกเปลี่ยนเป็น ID เฉพาะที่สามารถใช้ในแบบสอบถาม WMIC WMIC ถูกเรียกใช้ภายในคำสั่ง FOR / F ซึ่งหมายความว่ามันกำลังทำงานอยู่ในกระบวนการ child cmd.exe นั่นคือเหตุผลที่ ParentProcessID ของกระบวนการ cmd.exe ถูกดึง


7

ขยายคำตอบของ Tony Roth:

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

การใช้ตัวกรอง WINDOWTITLE หลีกเลี่ยงไปป์เพื่อให้คุณสามารถใส่ไว้ในวงสำหรับและกำหนดให้กับตัวแปรด้วย SET หากคุณต้องการ:

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

การเอาออก/vทำให้เร็วขึ้นและ/NHกำจัดบรรทัดส่วนหัว คุณต้องการ wildcard หลังจากนั้น"uniqueTitle"เพราะหัวเรื่องของหน้าต่างมีคำสั่งปัจจุบันจริง ๆ (ดังนั้นมันจะดำเนินต่อไปเรื่อย ๆ หากคุณพยายามจับคู่ทั้งหมด)


6

ใช้ PowerShell + WMI:

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

นีซ; ถ้าคุณมี PowerShell หลักจะได้รับง่ายยิ่งขึ้น (แม้ว่าคำสั่งจะไม่เป็นไปอย่างรวดเร็ว ):pwsh -noprofile -c "(Get-Process -Id $PID).Parent.Id"
mklement

5
  1. ตัวจัดการงาน Windows คุณจะต้องไปที่มุมมอง -> เลือกคอลัมน์ .. แล้วเลือก PID
  2. "tasklist / v" เพื่อรับข้อมูลงาน verbose ใน command prompt
  3. Process Explorer จากlive.sysinternals.com

2
@Vivek จากพรอมต์คำสั่ง ... และคุณกำลังทำ
ซ้ำ

ฉันเพิ่งให้ตัวเลือกที่เป็นไปได้ทั้งหมด .. และไม่มีการทำซ้ำ .. ฉันอาจกล่าวถึง PowerShell ด้วยเช่นกัน แต่ฉันควบคุมตัวเองเนื่องจากไม่ได้มาเป็นค่าเริ่มต้นใน XP และ 2003 หากเป็นเช่นนี้สำหรับ Vista เป็นต้นไประบบปฏิบัติการใช่ 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


3

หากคุณต้องการค้นหา PID ของ imagename "notepad.exe" รหัสต่อไปนี้จะทำงานให้คุณ:

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

2

หากคุณมีชุดทรัพยากร Windows 2003 ให้ส่งผ่าน 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

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%

คำอธิบาย:

- จะไม่เป็น PID สำหรับ cmd.exe ที่มากกว่า 18100 ดังนั้นตรวจสอบว่า PID2 มากกว่า 8100 หรือไม่ดังนั้นเรารู้ว่าเป็นตัวเลข 4 หลักหรือ 5 หลัก

กรณีที่ 1: PID 5 หลักเช่น 17504 มี PID1 val 17504 และ PID2 val ของ 1750 ดังนั้นเราจึงใช้ PID1

กรณีที่ 2: PID 4 หลักเช่น 8205 มี PID1 val ของ 8205 "และ PID2 val ของ 8205 ดังนั้นเราจึงใช้ PID2

กรณีที่ 3: PID 4 หลักเช่น 4352 มี PID1 val ของ 4352 "และ PID2 val ของ 4352 ดังนั้นเราจึงใช้ PID2

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.