获取在Bat文件中运行的exe的进程ID

时间:2014-02-07 03:45:20

标签: windows batch-file batch-processing

我需要在我的bat文件中运行的“Las2xyz”进程的进程ID。

我怎样才能做到这一点?我不能使用最后一个RUN ID或第一个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"

有人告诉我该怎么做! 谢谢

3 个答案:

答案 0 :(得分:12)

这将启动一个可执行文件并获取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

答案 1 :(得分:8)

使用tasklist

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

答案 2 :(得分:5)

延长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传递怎么办?

有一个解决方案。但它不漂亮;-)我首先在Escaping strings when using 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