通过命令行获取新创建的进程ID

时间:2016-05-23 05:26:29

标签: windows batch-file command-line

如果我在批处理文件中使用命令行启动新进程。 如何获得新创建的进程ID。

//在批处理文件中

C:\用户\ PRASHANT>记事本

这里我打开了一个新的记事本进程,如何获得记事本进程ID

3 个答案:

答案 0 :(得分:1)

for /f "tokens=2 delims==;" %A in ('wmic process call create notepad ^| findstr /i /c:processid') do set pid=%A
set pid=%pid:~1,4%

这启动程序使用WMIC返回PID。 Findstr删除额外的行,第二行处理WMIC的uniciode。

答案 1 :(得分:0)

您可以提前启动批处理文件,不断地将任务列表转储到文本文件中,只检索第一个列(内存大小可能会不断更改)并将其写入tasks_now.txt

FOR /F "tokens=1,2 delims=, skip=1" %%f IN ('tasklist /FO:CSV') DO ( echo %%f %%g >> tasks_now.txt )

然后,您可以使用文件比较命令将tasks_now.txt与tasklist进行比较:

fc tasks_now.txt tasks_earlier.txt > diff.txt

如果%errorlevel%为0,则不会发生任何差异,也不会创建新进程。现在你将_now复制到_earlier进行下一轮。

否则,您可以在diff.txt上运行FIND以查找新进程。如果在可能需要签入tasks_earlier.txt之前已经存在同名的任务,如果它已经存在(再次使用FIND) - 如果没有,那么你就有了新的任务。

答案 2 :(得分:0)

您需要wmic来创建流程并在一次操作中获取其流程ID。

基本原则是:

for /f "usebackq tokens=2 delims=;= " %%A IN (`wmic process call create '"notepad","%cd%",null'  ^|find "ProcessId"`)  do set /A PID=%%A

notepad是要运行的命令行,%cd%是工作目录(在本例中是当前目录)。

之后,您应该在%PID%

中拥有PID

但是,有一些引用问题涉及更复杂的命令行和参数。有一个更复杂但更健壮的脚本正是这样做的,我在这里找到:http://ss64.org/viewtopic.php?pid=5876#p5876

代码,在ss64.org上为用户smerch提供信用:

@echo off
setlocal enabledelayedexpansion

if "%~1" NEQ "" (
  if "%~1" NEQ "-help" (
      call :proc %*
      exit /b %ERRORLEVEL%
  )
)

call :echoHelp
exit /b

:proc
  call :argParser %*

  if "%exec%" EQU "" (
      call :err 1000
      exit /b %ERRORLEVEL%
  )

  if "%host%" NEQ "" (
      set host=/NODE:%host%
      if "%user%" NEQ "" (
          set user=/USER:%user%
          if "%pass%" NEQ "" (
              set pass=/PASSWORD:%pass%
          )
      )
  )

  if "%record%" NEQ "" (
      set record=/RECORD:%record%
  )

  set global_params=%record% %host% %user% %pass%

  for /f "usebackq tokens=*" %%G IN (`wmic  %global_params%  process call create "%exec% %commandline%"^,"%workdir%"`) do ( 
      rem echo %%G
      set _tmp=%%G
      set _tmp=!_tmp:^>=^^^>!
      echo !_tmp! | find "ProcessId" > nul && (
          for /f  "tokens=2 delims=;= " %%H in ('echo !_tmp!') do (
              call set /A PID=%%H
          )
      )
      echo !_tmp! | find "ReturnValue" > nul && (
          for /f  "tokens=2 delims=;= " %%I in ('echo !_tmp!') do (
              call set /A RETCOD=%%I
          )
      )
      call :concat
  )
  set _tmp=

  rem successful execution
  if "%PID%" NEQ "" (
      echo %PID%
      exit /b
      rem exit /B %PID%
  ) else (
      call :err %RETCOD%
  )
exit /b %ERRORLEVEL%


:concat

  call set output=%output% ^& echo !_tmp:^>=^^^>!
exit /b

:argParser

  set comstr=-exec-commandline-workdir-host-user-pass-record
  :nextShift
  set /A shifter=shifter+1
  echo %comstr% | find "%~1" > nul && (
      set _tmp=%~1
      set !_tmp:-=!=%~2
  )
  shift & shift
  if %shifter% LSS 7 goto :nextShift
  set _tmp=
  set shifter=
exit /b

:echoHelp

  echo %~n0 -exec executubale {-commandline command_line} { -workdir working_directory} 
  echo  {-host  remote_host {-user user {-pass password}}} {-record path_to_xml_output}
  echo\
  echo localhost cant' be used as in -host variable
  echo Examples:
  echo %~n0  -exec "notepad" -workdir "c:/"  -record "test.xml" -commandline "/A startpid.txt"
  echo %~n0  -exec "cmd" -workdir "c:/"  -record "test.xml" -host remoteHost -user User
exit /b

:err
  if %1 EQU 2          (set errmsg=Access Denied)
  if %1 EQU 3          (set errmsg=Insufficient Privilege)
  if %1 EQU 8          (set errmsg=Unknown failure ^& echo Hint: Check if the executable and workdit exists or if command line parameters are correct.)
  if %1 EQU 9          (set errmsg=Path Not Found ^& echo Hint: check if the workdir exists on the remote machine.)
  if %1 EQU 21         (set errmsg=Invalid Parameter ^& echo Hint: Check executable path. Check if host and user are corect.)
  if %1 EQU 1000       (set errmsg=Executable not defined.)
  if "%errmsg:~0,1%" EQU "" (set errmsg=%output% ^& echo Hint: brackets, quotes or commas in the password may could breack the script.)

  echo %errmsg%
exit /b %1