web-dev-qa-db-ja.com

Batファイルで実行されているexeのプロセスIDを取得する

Batファイルで実行されている「Las2xyz」プロセスのプロセスIDが必要です。

どうすればこれを達成できますか?最後のRUNIDまたは最初のIDを使用できません。実際のプロセスIDが必要です。これらは常に実行されており、いつでも終了するため、推測できません。

これは私のバッチです:

@echo off
@echo off
set PATH=C:\Windows\system32;C:\atlass\las2xyz;C:\atlass\las2xyz\bin;C:\atlass\las2xyz\lib
set TOP_HOME=%C:\atlass\las2xyz%
del dat*.xyz dat*.seg dat*.pat dat*.tmp dat*.txt test.nam
las2xyz.exe "[ flightpath 2 out 5 lasformat 1 target 0 FIXCLASS 1 step 20 unit *METRIC* fov 20.0 rollfix 1   sn_number *H68_038-003* lsystem *LIDAR_1* DESTSYS 144 minele -100.00 maxele 6000.00 hoff 0.00 eoff 0.00 noff 0.00 bootnr 13110201 leg 1]" "C:\Users\Developer-One\Desktop\las2xyz_Data\131102_003243_GPE.sdc" , "\\192.168.0.102\agis\Macquarie_Barwon_1310\Area_01\sbet_038_13110201.out" - "131102_003243_cov"

誰かが私にそれをする方法を教えてくれます!ありがとうございました

5
Dean

これにより、実行可能ファイルが起動し、PIDが取得されます。

@echo off
for /f "tokens=2 delims==; " %%a in (' wmic process call create "notepad.exe" ^| find "ProcessId" ') do set PID=%%a
echo "%PID%"
pause
12
foxidrive

tasklistを使用します

for /f "tokens=2" %%a in ('tasklist^|find /i "Las2xyz"') do (set pid=%%a)
9
Rafael

Foxidriveの回答を拡張して、引数を必要とするOPの呼び出しを表示します。

set "exe=las2xyz.exe"
set "arg1=[ flightpath 2 out 5 lasformat 1 target 0 FIXCLASS 1 step 20 unit *METRIC* fov 20.0 rollfix 1   sn_number *H68_038-003* lsystem *LIDAR_1* DESTSYS 144 minele -100.00 maxele 6000.00 hoff 0.00 eoff 0.00 noff 0.00 bootnr 13110201 leg 1]"
set "arg2=C:\Users\Developer-One\Desktop\las2xyz_Data\131102_003243_GPE.sdc"
set "arg3=\\192.168.0.102\agis\Macquarie_Barwon_1310\Area_01\sbet_038_13110201.out"
set "arg4=131102_003243_cov"

for /f "tokens=2 delims==; " %%A in (
  'wmic process call create '"%exe%" "%arg1%" ^, "%arg2%" "%arg3%" - "%arg4%"' ^| find "ProcessId"'
) do set "PID=%%A"
echo "%PID%"

引用符で囲まれた引数の内容には、二重引用符またはコンマを除いて、ほとんど何でも含めることができます。引数の間にコンマを使用する場合は、エスケープする必要があります。

引数内にコンマを許可する別の構文があるかもしれませんが、引数内に括弧を使用することはできません。

では、コマンドラインをWMIC PROCESS CALL CREATEに渡せない場合はどうすればよいでしょうか?

解決策があります。しかし、それはきれいではありません;-)私は最初にこれを投稿しました wmicを使用するときに文字列をエスケープする

@echo off
setlocal enableDelayedExpansion

:: Get the PID and UID for this batch process
call :getMyPID

:: Initialize an existing PIDs list
set "PIDs= "

:: Get a list of all existing child processes, except for the
:: child CMD.EXE process that was created by this FOR /F loop.
:: This is necessary because the console session that this script
:: is running in might have previously created a child process.
for /f %%A in (
  '2^>nul wmic process where "ParentProcessID=%myPID% and not CommandLine like '%%<%UID%>%%'" get ProcessID'
) do for %%B in (%%A) do set "PIDs=!PIDs!%%B "

:: Create your new process as you normally would.
:: For this demonstration, I will simply create a new CMD.EXE session 
start

:: Get the PID of the newly created child process by getting all child PIDs,
:: except for the child CMD.EXE process that was created by this FOR /F loop.
:: Ignore any PID that already exists in the %PIDs% list. The only PID left
:: is your new process.
for /f %%A in (
  '2^>nul wmic process where "ParentProcessID=%myPID% and not CommandLine like '%%<%UID%>%%'" get ProcessID'
) do for %%B in (%%A) do if "!PIDs: %%B =!" equ "!PIDs!" set "PID=%%B"

:: At this point you could append the new PID to the PIDs list using
::   set "PIDs=!PIDs!%PID% "
:: Then you can repeat the steps of creating a new proces and getting the new PID
::
:: But instead, I will simply show the result and exit
echo new PID=%PID%

exit /b


:getMyPID 
setlocal disableDelayedExpansion

:getLock

:: Establish a nearly unique temp file name using %time%
set "lock=%temp%\%~nx0.%time::=.%.lock"

:: Transform the full path into a UID that can be used in a WMIC query
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%"


:: Establish an exclusive lock on the temp file
:: If this fails, then loop back and try again until success
:: This guaranees no two process will ever have the same UID
2>nul ( 9>"%lock%" (

  %= The FOR /F loops creates a child CMD.EXE process which in turn invokes WMIC.         =%
  %= The child CMD.EXE process contains the WMIC query with the UID in its command line.  =%
  %= The WMIC query identifies the CMD.EXE process with the UID in the command line,      =%
  %= and returns the parent process ID, which happens to be the PID for this batch script =%
  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 ) %= Guarantee success so we don't accidently loop again =%

))||goto :getLock

:: Delete the temp file
del "%lock%" 2>nul

:: Return the result
( endlocal
  set "myPID=%PID%"
  set "UID=%uid%"
)
exit /b
5
dbenham