Windows'taki komut isteminden kendi işlem pid'imi nasıl alabilirim?


26

im komut isteminden kendi PID'imi almanın bir yolunu bulmaya çalışıyorum (yarasa komut dosyalarında daha sonra kullanmak için), şimdiye kadar bulduğum tek kullanışlı yol getpids.exe'yi buradan kullanmaktı: http://www.scheibli.com/ projects / getpids / index.html ancak pencerelere "yerleşik" bir komut arıyorum

düzenleme: im "kurşun geçirmez" bir yol arıyorum - benim süreç hakkında sadece cmd.exe ya da bir şey olduğu hakkında hiçbir varsayım

Yanıtlar:


36

Diğer çözümlerin hiçbiri kurşun geçirmez ve yerleşik olmadığından, aşağıdaki çözümü önereceğimi düşündüm, ancak sonuçları bir şekilde ayrıştırmanız / kaydetmeniz gerekeceğini unutmayın:

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

Bu gerçekten temiz. Şu anki zaman + bazı rasgele üretilen bir sayı kurşun geçirmez almak için başlık olarak ayarlanabilir
eminim

3
Bir zamanlayıcınız toplu komut dosyanızı aynı anda iki kez çağırıyorsa,% random%% +% time% kullanmayın. Aynı betiğin aynı anda farklı parametrelerle çağrılması sorununu yaşadım. Rastgele için tohum aynıydı ve geçici bir dizin oluştururken çarpışmalara girdim. Geçici dizini oluştururken hatayı idare etmenin bir yolu yoktu. Uzun lafın kısası, senaryonuzun aynı anda iki kez kovulmadığını varsayabilirseniz, bu numara işe yaramalı.
Peter Schuetze

Daha kesin bir zaman damgası ( microseconds% 1 gibi% 100 saniye gibi) dahil olmak üzere , (bu şekilde derinden test edilmemiş olabilir) bu durumda daha güvenilir olacaktır: wmic os get LocalDateTime(YearMonthDayHourMinuteSecond.Microsecond + Timezone). Zamanlayıcı aynı mikrosaniyede iki şeyi çalıştıramazsa ...
Gauthier Boaglio

İşlem bilgisayarda başka bir oturumda çalışıyorsa, başlık N / A
FrinkTheBrave

Bu, ana işlemin PID'sini verir.
access_granted

7

Kullanıcının WMIC ve TEMP puanlarına, kullanıcının yazma ayrıcalıklarına sahip olduğu geçerli bir yolu göstermesi şartıyla, kurşun geçirmez olduğuna inanıyorum. Bu, http://www.dostips.com/forum/viewtopic.php?f=3&t=6133 adresindeki bazı ortak çalışmaların sonucudur .

@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

Komut dosyası, geçerli saati adıyla birleştiren geçici bir dosyaya özel bir kilit oluşturur. İki benzer adlandırılmış toplu işlem PID'yi aynı 0.01 saniye zaman aralığında almaya çalıştığında ancak bir tanesinin başarılı olacağı bir çarpışma olabilir.

Başarısız olan herhangi bir işlem tekrar tekrar geri dönecek ve başarılı olana kadar yeni bir kilit dosyası yolu ile tekrar deneyecektir.

Kilit dosyasına giden tam yol, WMIC sorgusunda kullanılabilecek benzersiz bir kimliğe dönüştürülür. WMIC bir FOR / F komutunda çalıştırılır, bu bir alt cmd.exe işleminde çalıştığı anlamına gelir. Bu nedenle cmd.exe işleminin ParentProcessID değeri alındı.


7

Tony Roth'un cevabını genişletmek:

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

WINDOWTITLE filtresini kullanmak boruyu önler, böylece for for döngüsüne koyabilir ve isterseniz SET ile bir değişkene atayabilirsiniz:

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

Çıkarma işlemi /vdaha hızlı hale gelir ve /NHbaşlık satırından kurtulur. Sonrasında joker karaktere ihtiyacınız vardır, "uniqueTitle"çünkü pencere başlığı aslında geçerli komutu içerir (tam olarak eşleştirmeye çalışırsanız devam eder ve devam eder).


6

PowerShell + WMI Kullanımı:

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

Güzel; PowerShell Çekirdeğiniz varsa , daha da kolaylaşır (her iki komut da hızlı olmamasına rağmen ):pwsh -noprofile -c "(Get-Process -Id $PID).Parent.Id"
mklement

5
  1. Windows Görev Yöneticisi, Görünüm -> Sütun Seç .. ve PID'yi seçmeniz gerekir.
  2. "tasklist / v" komut isteminde ayrıntılı görev bilgileri almak için.
  3. Live.sysinternals.com dan Explorer Gezgini .

2
@Vivek, bir komut isteminden ... ve siz yanıtları
yineliyorsunuz

Ben sadece mümkün olan tüm seçenekleri verdim .. ve yineleme yok .. PowerShell'den de bahsettim ama XP ve 2003'te varsayılan olarak gelmeyeceği için kendimi sınırlandırdım. .
Vivek Kumbhar

5

Çalışan yalnızca bir cmd.exe olduğunu biliyorsanız, PID'yi şu şekilde alabilirsiniz:

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

echo %pid%

Bu kabul edilemez bir varsayıma benziyor, kodunuz lapa lapa olabilir
Raúl Salinas-Monteagudo

Raul, ne dediğini anlıyorum. Pek çok durumda güvensizdir, ancak bazılarında güvenlidir - kiosk sistemi veya hangi işlemlerin
başladığına


3

Imaename "notepad.exe" nin PID'sini bulmak istiyorsanız, aşağıdaki kod sizin için çalışacaktır:

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

2

Windows 2003 Kaynak setine sahipseniz, istediğiniz satırı elde etmek için qgrep'e itin. Pid'i buradan çıkarabilirsiniz (bu, bir seferde yalnızca bir cmd çalıştığını varsayar),

tasklist /v | qgrep cmd

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


0

BU AÇIK CMD İÇİN İŞLEM KİMLİĞİ ALMAK İÇİN KISA YOL

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

0

Bu cevap SADECE süreç kimliğini ve en üstteki cevabın içerdiği fazladan hiçbir şeyi vermeyecektir.

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%

Açıklama:

-te cmd.exe için 18100'den büyük bir PID olmayacak, bu yüzden PID2'nin 8100'den büyük olup olmadığını kontrol et, yani 4 basamaklı mı yoksa 5 basamaklı mı olduğunu öğrendik

durum 1: 17504 gibi 5 basamaklı bir PID, 17504 val değerine sahip bir PID1 değerine ve 1750 val değerine sahip bir PID2 değerine sahiptir;

durum 2: 8205 gibi 4 basamaklı bir PID 8205 "değerinde bir PID1 değerine ve 8205 değerinde bir PID2 değerine sahip, bu yüzden PID2 kullanıyoruz

durum 3: 4352 gibi 4 basamaklı bir PID, 4352 değerinde bir PID1 değerine ve 4352 değerinde bir PID2 değerine sahiptir, bu yüzden PID2 kullanıyoruz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.