Запуск программ при помощи функции 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