Запуск программ при помощи CreateProcess()

Запуск программ при помощи функции Windows API CreateProcess() иногда позволяет более гибко управлять параметрами запускаемого приложения, чем функция Run Clarion-a и даже ShellExecute.
Так как при запуске программы при помощи CreateProcess() мы знаем хендл процесса, то появляется возможность дальнейшего управления программой через этот хендл (например, ее принудительного завершения)  или определения ее состояния (активна или уже завершена).

Вот прототипы используемых функций:

! BOOL CreateProcess(
! LPCTSTR               lpApplicationName,   // name of executable module
! LPTSTR                lpCommandLine,       // command line string
! LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
! LPSECURITY_ATTRIBUTES lpThreadAttributes,  // SD
! BOOL                  bInheritHandles,     // handle inheritance option
! DWORD                 dwCreationFlags,     // creation flags
! LPVOID                lpEnvironment,       // new environment block
! LPCTSTR               lpCurrentDirectory,  // current directory name
! LPSTARTUPINFO         lpStartupInfo,       // startup information
! LPPROCESS_INFORMATION lpProcessInformation // process information
! );
CreateProcess(Long,Long,Long,Long,Bool,DWORD,Long,Long,Long,Long),BOOL,RAW,PASCAL,NAME('CreateProcessA')
GetExitCodeProcess(HANDLE hProcess, Long lpExitCode),BOOL,RAW,PASCAL
TerminateProcess(HANDLE,UNSIGNED),BOOL,PASCAL

Используемые структуры, переменные и константы:
STATUS_PENDING Equate( 00000103h )
STILL_ACTIVE   Equate( STATUS_PENDING )

ProcessInfo GROUP,PRE( PI )
PI:HProcess    HANDLE
PI:HTread      HANDLE
PI:DWProcess   DWORD
PI:DWTread     DWORD
            END

! dwCreationFlag values:
!----------------------------------------
DEBUG_PROCESS           Equate( 00000001h )
DEBUG_ONLY_THIS_PROCESS Equate( 00000002h )

CREATE_SUSPENDED        Equate( 00000004h )

DETACHED_PROCESS        Equate( 00000008h )

CREATE_NEW_CONSOLE      Equate( 00000010h )

NORMAL_PRIORITY_CLASS   Equate( 00000020h )
IDLE_PRIORITY_CLASS     Equate( 00000040h )
HIGH_PRIORITY_CLASS     Equate( 00000080h )
REALTIME_PRIORITY_CLASS Equate( 00000100h )

CREATE_NEW_PROCESS_GROUP   Equate( 00000200h )
CREATE_UNICODE_ENVIRONMENT Equate( 00000400h )

CREATE_SEPARATE_WOW_VDM    Equate( 00000800h )
CREATE_SHARED_WOW_VDM      Equate( 00001000h )
CREATE_FORCEDOS            Equate( 00002000h )

CREATE_DEFAULT_ERROR_MODE  Equate( 04000000h )
CREATE_NO_WINDOW           Equate( 08000000h )

STARTF_USESHOWWINDOW    Equate( 00000001h )
STARTF_USESIZE          Equate( 00000002h )
STARTF_USEPOSITION      Equate( 00000004h )
STARTF_USECOUNTCHARS    Equate( 00000008h )
STARTF_USEFILLATTRIBUTE Equate( 00000010h )
STARTF_RUNFULLSCREEN    Equate( 00000020h )  ! ignored for non-x86 platforms
STARTF_FORCEONFEEDBACK  Equate( 00000040h )
STARTF_FORCEOFFFEEDBACK Equate( 00000080h )
STARTF_USESTDHANDLES    Equate( 00000100h )

! cstrReserved  CString( '' )
! cstrDesktop   CString( '' )
! cstrTitle     CString( '' )
! byteReserved2 Byte( 0 )

STARTUPINFO GROUP,PRE( SI )
SI:cb          DWORD
SI:lpReserved  ULong
SI:lpDesktop   ULong
SI:lpTitle     ULong
SI:dwX         DWORD
SI:dwY         DWORD
SI:dwXSize     DWORD
SI:dwYSize     DWORD
SI:dwXCountChars   DWORD
SI:dwYCountChars   DWORD
SI:dwFillAttribute DWORD
SI:dwFlags      DWORD
SI:wShowWindow  WORD
SI:cbReserved2  WORD
SI:lpReserved2  ULong
SI:hStdInput    HANDLE
SI:hStdOutput   HANDLE
SI:hStdError    HANDLE
            END
! Команды  ShowWindow

SW_HIDE             Equate(0)
SW_SHOWNORMAL       Equate(1)
SW_NORMAL           Equate(1)
SW_SHOWMINIMIZED    Equate(2)
SW_SHOWMAXIMIZED    Equate(3)
SW_MAXIMIZE         Equate(3)
SW_SHOWNOACTIVATE   Equate(4)
SW_SHOW             Equate(5)
SW_MINIMIZE         Equate(6)
SW_SHOWMINNOACTIVE  Equate(7)
SW_SHOWNA           Equate(8)
SW_RESTORE          Equate(9)
SW_SHOWDEFAULT      Equate(10)
SW_FORCEMINIMIZE    Equate(11)
SW_MAX              Equate(11)
Вот пример запуска программы (команды ДОС) в "скрытом" окне 
с ожиданием ее завершения:
loc:AppName    CSTRING(255)
loc:Argum      CSTRING(255)
loc:StartPath  CSTRING(255)
loc:ExitCode   ULONG 
loc:RemotePath CSTRING(255)
 code
 SI:cb = size(STARTUPINFO)
 SI:lpReserved = 0  !address(cstrReserved)
 SI:lpDesktop  = 0  !address(cstrDesktop)
 SI:lpTitle    = 0  !address(cstrTitle)
 SI:dwX = 0
 SI:dwY = 0
 SI:dwXSize = 0
 SI:dwYSize = 0
 SI:dwXCountChars = 0
 SI:dwYCountChars = 0
 SI:dwFillAttribute = 0
 SI:dwFlags = STARTF_USESHOWWINDOW
 SI:wShowWindow = SW_HIDE
 SI:cbReserved2 = 0
 SI:lpReserved2 = 0  !address(byteReserved2)
 SI:hStdInput  = 0
 SI:hStdOutput = 0
 SI:hStdError  = 0

 PI:HProcess = 0
 PI:DWProcess = 0
! loc:AppName = 'net.exe'
 loc:Argum   = 'net.exe use y: ' & clip(sub( cod:LocPath,1,len(clip(cod:LocPath))-1) )
 loc:StartPath = path()
 loc:RemotePath = '\\Server01\ShareName1'

 r# = CreateProcess( 0,address(loc:Argum),0,0,0,NORMAL_PRIORITY_CLASS,0,address(loc:StartPath),address(StartupInfo),address(ProcessInfo) )
 if r# = True
!   Message( 'PI:HProcess = ' & PI:HProcess )
 .
 ! Цикл ожидания завершения команды
 loop
  r# = GetExitCodeProcess( PI:HProcess, address(loc:ExitCode) )
  if r#<>0
    if loc:ExitCode<>STILL_ACTIVE  ! 259
      break
    .
  else
    break
!   Message( 'Error GetExitCodeProcess' )
  .
 . ! end loop

 

Hosted by uCoz