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