विंडोज़ में कमांड प्रॉम्प्ट से स्वयं की प्रक्रिया कैसे प्राप्त करें


26

एक कमांड प्रॉम्प्ट (बाद में बैट स्क्रिप्ट में उपयोग करने के लिए) से अपना खुद का पीआईडी ​​प्राप्त करने का एक तरीका खोजने की कोशिश कर रहा हूं, अब तक मैंने जो एकमात्र उपयोगी तरीका पाया है वह यहां से getpids.exe का उपयोग करना था: http://www.scheibli.com/ परियोजनाओं / getpids / index.html, लेकिन विंडोज़ के लिए "में निर्मित" एक कमांड की तलाश में है

संपादित करें: एक "बुलेट प्रूफ" तरीके की तलाश कर रहा हूं - मेरी प्रक्रिया के बारे में कोई धारणा केवल cmd.exe या कुछ भी नहीं है

जवाबों:


36

चूंकि अन्य समाधानों में से कोई भी बुलेटप्रूफ नहीं है और इसमें निर्मित है, मुझे लगा कि मैं निम्नलिखित समाधान की पेशकश करूंगा, लेकिन ध्यान दें कि आपको परिणामों को किसी तरह पार्स / सहेजने की आवश्यकता होगी:

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

यह वास्तव में साफ है। मुझे पूरा यकीन है कि वर्तमान समय + कुछ यादृच्छिक रूप से उत्पन्न संख्या को बुलेटप्रूफ के पास प्राप्त करने के लिए शीर्षक के रूप में सेट किया जा सकता है
राडार 29:10

3
यदि आपके पास एक शेड्यूलर कॉल करने के लिए एक ही समय में दो बार% यादृच्छिक% +% समय का उपयोग न करें। मेरे पास यह मुद्दा था कि एक ही स्क्रिप्ट को एक ही समय में विभिन्न मापदंडों के साथ बुलाया गया था। यादृच्छिक के लिए बीज समान था और मैं एक अस्थायी निर्देशिका बनाते समय टकराव में भाग गया। अस्थायी निर्देशिका बनाते समय त्रुटि को संभालने के लिए कोई रास्ता नहीं था। लंबी कहानी छोटी, यदि आप यह मान सकते हैं कि आपकी स्क्रिप्ट एक ही समय में दो बार निकाल नहीं जाती है, तो यह चाल काम करना चाहिए।
पीटर शुएत्ज़े

हो सकता है (गहराई से परीक्षण न किया गया हो) जो एक अधिक सटीक टाइमस्टैम्प प्राप्त कर रहा हो (जिसमें microseconds% समय% की तरह 1/100 सेकंड शामिल है), इस मामले में अधिक विश्वसनीय होगा: wmic os get LocalDateTime(वर्षमूर्तिडयूरहॉर्मिन्यूटसेकंड। माइकोसेकेंड + टाइमज़ोन)। जब तक कि शेड्यूलर एक ही माइक्रोसेकंड में दो चीजें चलाने में सक्षम नहीं हो जाता ...
Gauthier Boaglio

यदि यह प्रक्रिया कंप्यूटर पर किसी अन्य सत्र में चल रही है तो यह काम नहीं करेगा क्योंकि शीर्षक को N / A
FrinkTheBrave

यह मूल प्रक्रिया के PID देता है।
एक्सेस_ग्रेटेड

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

स्क्रिप्ट अस्थायी फ़ाइल पर एक अनन्य लॉक स्थापित करती है जो वर्तमान समय को नाम में शामिल करती है। केवल एक टक्कर हो सकती है अगर नामित बैच प्रक्रियाओं में से दो समान 0.01 सेकंड के अंतराल के भीतर पीआईडी ​​प्राप्त करने का प्रयास करते हैं, जिस स्थिति में केवल एक ही सफल होगा।

कोई भी प्रक्रिया जो विफल होती है वह बार-बार लूप बैक करेगी और नए लॉक फाइल पथ के साथ फिर से प्रयास करेगी जब तक कि वह सफल न हो जाए।

लॉक फ़ाइल का पूरा पथ एक अद्वितीय आईडी में बदल जाता है जिसका उपयोग WMIC क्वेरी में किया जा सकता है। WMIC को FOR / F कमांड के भीतर चलाया जाता है, जिसका अर्थ है कि यह चाइल्ड cmd.exe प्रक्रिया में चल रहा है। यही कारण है कि cmd.exe प्रक्रिया के पेरेंटप्रोसेस को पुनर्प्राप्त किया जाता है।


7

टोनी रोथ के जवाब पर विस्तार:

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हो जाता है और हेडर लाइन से छुटकारा मिल जाता है। आपको वाइल्डकार्ड की आवश्यकता है "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. विंडोज टास्क मैनेजर, आपको व्यू -> कॉलम का चयन करें .. और PID का चयन करना होगा।
  2. "कार्यसूची / वी" कमांड प्रॉम्प्ट में वर्बोज़ कार्य जानकारी प्राप्त करने के लिए।
  3. Live.sysinternals.com से प्रोसेस एक्सप्लोरर ।

2
@ विवेक, एक कमांड प्रॉम्प्ट से ... और आप जवाब दे रहे हैं
वूयेक

मैंने बस सभी संभावित विकल्प दिए हैं .. और कोई डुप्लिकेटिंग नहीं है .. मैं पॉवरशेल का भी उल्लेख कर सकता था, लेकिन मैंने खुद को संयमित किया, क्योंकि यह XP और 2003 में डिफ़ॉल्ट रूप से नहीं आता है। यदि यह विस्टा पर ओएस के लिए है, तो हाँ पॉवरशेल मेरी प्राथमिकता होगी ।
विवेक कुंभार

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%

यह एक अनुचित धारणा की तरह लगता है, आपका कोड परतदार हो सकता है
राउल सेलिनास-मोंटियागुडो

राउल, मैं समझता हूँ कि तुम क्या कह रहे हो। यह कई मामलों में असुरक्षित है, लेकिन कुछ में सुरक्षित है - जैसे किओस्क सिस्टम या एक वीएम जहां आप कुल नियंत्रण में हैं कि क्या प्रक्रियाएं शुरू हो रही हैं और क्या नहीं
zumalifeguard

4

यह काम कर जाना चाहिए:

टास्कलिस्ट / वी


3

यदि आप "नोटपैड.एड" की कल्पना का पीआईडी ​​ढूंढना चाहते हैं, तो निम्न कोड आपके लिए काम करेगा:

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

2

यदि आपको Windows 2003 संसाधन किट मिली है, तो इसे qgrep के माध्यम से धक्का दें ताकि आप अपनी इच्छित लाइन प्राप्त कर सकें। तब आप यहाँ से पिड निकाल सकते हैं (यह मानता है कि आपको एक बार में केवल एक cmd चल रहा है),

tasklist /v | qgrep cmd

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

1

इस छोटी सी बैच ट्रिक पर एक नजर । यह cmd का शीर्षक एक विशेष मान पर सेट करता है, फिर इसे खोजने के लिए टास्कलिस्ट का उपयोग करता है। आविष्कारशील

\\ ग्रेग


0

यह लघु सीएमडी के लिए प्रक्रिया आईडी प्राप्त करने के लिए किया जाएगा

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

0

यह उत्तर आपको केवल प्रक्रिया आईडी देगा, और अतिरिक्त सामान में से कोई भी शीर्ष उत्तर शामिल नहीं है।

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%

स्पष्टीकरण:

-cmere cmd.exe के लिए ऐसा PID नहीं होगा जो 18100 से अधिक है, इसलिए जांचें कि PID2 8100 से अधिक है या नहीं, तो हम जानते हैं कि क्या यह 4 अंकों या 5 अंकों की संख्या है

केस 1: 17504 जैसे 5 अंकों के पीआईडी ​​में पीआईडी ​​1 वैल 17504 और पीआईडी ​​2 वैल 1750 है, इसलिए हम पीआईडी ​​1 का उपयोग करते हैं।

केस 2: 8205 जैसे 4 अंकों के पीआईडी ​​में 8205 का पीआईडी ​​1 वैल है "और 8205 का पीआईडी ​​2 वैल है, इसलिए हम पीआईडी ​​2 का उपयोग करते हैं।

केस ३: ४३५२ की तरह ४ अंकों के पीआईडी ​​में ४३५२ का पीआईडी ​​१ वैल है और ४३५२ का पीआईडी ​​२ वैल है, इसलिए हम पीआईडी ​​२ का उपयोग करते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.