Software Archive
Read-only legacy content
17060 Discussions

Problem with CreateProcess

grtoro
Beginner
2,266 Views
My Quickwin program makes repeated calls to another program (which runs minimized) using CreateProcess. I followed the "startp" sample in the samples directory. I have noticed the following sequence of events:

a) During the second and later calls, CreateProcess returns a .false. value, although the called program has executed properly. My program then calls GetLastError, which returns zero (i.e., ERROR_SUCCESS (great name!)).

b) The call to CloseHandle(pi%hThread) returns 0 (error) and a call to GetLast Error returns 6 (ERROR_INVALID_HANDLE).

c) The call to WaitForSingleObject(pi%hProcess, -1) returns -1 and and a call to GetLast Error also returns 6.

d) The call to CloseHandle(pi%hProcess) returns 0 (error) and a call to GetLast Error also returns 6.

In spite of this, the calling and called program seem to be working OK, although I suspect there may be a large memory leak (I have had to reboot once). I have checked all non_null arguments to CreateProcess and nothing changes between the first and later calls. In particular, dwCreate is 144, si is zero except for si%CB=68,
si%DWFLAGS=1, si%WSHOWWINDOW=6, and pi is all zeros.

Does anyone have any suggestion on how to correct this problem?

Thanks,

Gabriel
0 Kudos
6 Replies
Jugoslav_Dujic
Valued Contributor II
2,266 Views
Hmm, something is really fishy here. Could you post some relevant code please, especially CreateProcess part? (please enclose code in
 ... 
HTML tags when posting so that it won't be screwed by Forum sogtware). Looks as if something is different in second call to CreateProcess but I cannot figure out why.

Jugoslav
0 Kudos
grtoro
Beginner
2,266 Views
 
! for createProcess

integer res
character szArgs*512 ! new process arguments buffer & temp pointer
character DirName*512 ! current DirName for new process
character szPgmName*(MAX_PATH) ! name of the program
logical(4) fSuccess ! API return code
type(T_STARTUPINFO) si ! used for CreateProcess
type(T_PROCESS_INFORMATION) pi ! used for CreateProcess

logical(4) bMoreParams ! flag end of new process parameter processing
logical(4) bWait ! wait/no wait for new process to end
integer dwResult ! API return code
integer dwCreate ! new process creation flags
integer bExtension ! input filename have an explicit extension?
integer SIZEOFSTARTUPINFO
integer SIZESECURITYATTRIBUTES
! integer i
character*5 aExt(4)
type(T_SECURITY_ATTRIBUTES) sa, sb
data DirName /'0'/
.
.
.

! run gs using create process
dwCreate = CREATE_NEW_CONSOLE
dwCreate = IOR(HIGH_PRIORITY_CLASS,dwCreate)!

SIZEOFSTARTUPINFO = 68
call ZeroMemory (LOC (si), SIZEOFSTARTUPINFO)
si%cb= SIZEOFSTARTUPINFO
!pi=T_PROCESS_INFORMATION(0,0,0,0) ! 4 integer*4 quantities
PI%hProcess =0
PI%hThread =0
PI%dwProcessId =0
PI%dwThreadId =0


!minimized
si%wShowWindow = SW_MINIMIZE
si%dwFlags = IOR(STARTF_USESHOWWINDOW, si%dwFlags)
!maximized
! si%wShowWindow = SW_SHOWMAXIMIZED
! si%dwFlags = IOR (STARTF_USESHOWWINDOW, si%dwFlags)

bWait=.true.

SIZESECURITYATTRIBUTES = 12
sa%nLength = SIZESECURITYATTRIBUTES
sa%lpSecurityDescriptor = NULL
sa%bInheritHandle = .true.

! IF ( .not. DlgInit( IDD_MAY_TAKE_TIME , dlg_modeless ) ) THEN
! WRITE (6,*) "Error: dialog not found: IDD_MAY_TAKE_TIME"
! ENDIF
! istat = DlgModeless( dlg_modeless )

fSuccess=.true.
!note: GS_CMD and GS_LIB are always read from the same file and do not change
fSuccess = CreateProcess( &
TRIM(GS_CMD)//CHAR(0), & ! image file name
TRIM(GS_LIB)//' @tree_tmp.gs'//CHAR(0), & ! command line (including program name)
NULL_security_attributes, & ! security for process
NULL_security_attributes, & ! security for main thread
.FALSE., & ! new process inherits handles?
dwCreate, & ! creation flags
NULL, & ! environment
null_character, & ! new current DirName
si, & ! STARTUPINFO structure
pi) ! PROCESSINFORMATION structure

if (fSuccess .EQV. .FALSE.) then
lasterror=GetLastError()
select case (lasterror) ! process common errors
case ( ERROR_SUCCESS ) ! great name!
continue
WRITE(6,*)'fsuccess was false but GetlastError returns 0'
case (ERROR_FILE_NOT_FOUND)
write (6,*) "Error: Ghostscript program not found"
!CALL DlgExit( dlg_modeless )
!CALL DlgUninit( dlg_modeless )
RETURN
case (ERROR_DIRECTORY)
write (6,*)("Error calling Ghostscript: bad starting directory")
!CALL DlgExit( dlg_modeless )
!CALL DlgUninit( dlg_modeless )
RETURN
case (ERROR_PATH_NOT_F
0 Kudos
grtoro
Beginner
2,266 Views
 
! for createProcess

integer res
character szArgs*512 ! new process arguments buffer & temp pointer
character DirName*512 ! current DirName for new process
character szPgmName*(MAX_PATH) ! name of the program
logical(4) fSuccess ! API return code
type(T_STARTUPINFO) si ! used for CreateProcess
type(T_PROCESS_INFORMATION) pi ! used for CreateProcess

logical(4) bMoreParams ! flag end of new process parameter processing
logical(4) bWait ! wait/no wait for new process to end
integer dwResult ! API return code
integer dwCreate ! new process creation flags
integer bExtension ! input filename have an explicit extension?
integer SIZEOFSTARTUPINFO
integer SIZESECURITYATTRIBUTES
! integer i
character*5 aExt(4)
type(T_SECURITY_ATTRIBUTES) sa, sb
data DirName /'0'/
.
.
.

! run gs using create process
dwCreate = CREATE_NEW_CONSOLE
dwCreate = IOR(HIGH_PRIORITY_CLASS,dwCreate)!

SIZEOFSTARTUPINFO = 68
call ZeroMemory (LOC (si), SIZEOFSTARTUPINFO)
si%cb= SIZEOFSTARTUPINFO
!pi=T_PROCESS_INFORMATION(0,0,0,0) ! 4 integer*4 quantities
PI%hProcess =0
PI%hThread =0
PI%dwProcessId =0
PI%dwThreadId =0


!minimized
si%wShowWindow = SW_MINIMIZE
si%dwFlags = IOR(STARTF_USESHOWWINDOW, si%dwFlags)
!maximized
! si%wShowWindow = SW_SHOWMAXIMIZED
! si%dwFlags = IOR (STARTF_USESHOWWINDOW, si%dwFlags)

bWait=.true.

SIZESECURITYATTRIBUTES = 12
sa%nLength = SIZESECURITYATTRIBUTES
sa%lpSecurityDescriptor = NULL
sa%bInheritHandle = .true.

! IF ( .not. DlgInit( IDD_MAY_TAKE_TIME , dlg_modeless ) ) THEN
! WRITE (6,*) "Error: dialog not found: IDD_MAY_TAKE_TIME"
! ENDIF
! istat = DlgModeless( dlg_modeless )

fSuccess=.true.
!note: GS_CMD and GS_LIB are always read from the same file and do not change
fSuccess = CreateProcess( &
TRIM(GS_CMD)//CHAR(0), & ! image file name
TRIM(GS_LIB)//' @tree_tmp.gs'//CHAR(0), & ! command line (including program name)
NULL_security_attributes, & ! security for process
NULL_security_attributes, & ! security for main thread
.FALSE., & ! new process inherits handles?
dwCreate, & ! creation flags
NULL, & ! environment
null_character, & ! new current DirName
si, & ! STARTUPINFO structure
pi) ! PROCESSINFORMATION structure

if (fSuccess .EQV. .FALSE.) then
lasterror=GetLastError()
select case (lasterror) ! process common errors
case ( ERROR_SUCCESS ) ! great name!
continue
WRITE(6,*)'fsuccess was false but GetlastError returns 0'
case (ERROR_FILE_NOT_FOUND)
write (6,*) "Error: Ghostscript program not found"
!CALL DlgExit( dlg_modeless )
!CALL DlgUninit( dlg_modeless )
RETURN
case (ERROR_DIRECTORY)
write (6,*)("Error calling Ghostscript: bad starting directory")
!CALL DlgExit( dlg_modeless )
!CALL DlgUninit( dlg_modeless )
RETURN
case (ERROR_PATH_NOT_F
0 Kudos
grtoro
Beginner
2,266 Views
continuation of code:

 
            case (ERROR_PATH_NOT_FOUND) 
                write (6,*) "Error calling Ghostscript: bad path" 
                !CALL DlgExit( dlg_modeless ) 
                !CALL DlgUninit( dlg_modeless ) 
                RETURN 
 
            case DEFAULT 
                 write (6,50) lasterror 
50               format ('Error  calling Ghostscript: GetLastError=',I5,' CreateProcess') 
                !CALL DlgExit( dlg_modeless ) 
                !CALL DlgUninit( dlg_modeless ) 
                RETURN 
        end select 
    end if 
 
    !  close pipe handle - child's instance will be closed when terminates 
    res= CloseHandle(pi%hThread) 
    if (res.eq.0) then 
      istat=GetLastError() 
    endif 
    if  (bWait .NEQV. .FALSE.) then !  wait /Wtime wait flag specified? 
      !   object to wait for 
      dwResult = WaitForSingleObject(pi%hProcess, -1) !  timeout time 
      if (dwResult == -1) then 
        write (6,150) GetLastError() 
150     format ('Error handling Ghostscript exit:  GetLastError=',I5,' WaitForSingleObject') 
      end if 
    end if 
    res= CloseHandle(pi%hProcess) !  close process handle or it won't die 
    if (res.eq.0) then 
      istat=GetLastError() 
    endif 
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,266 Views
I've pasted your code with minor changes (actually, I invoked cmd instead of GhostScript because I was lazy to investigate gs command line options and added an infinite loop instead of turning it into a subroutine) -- and it worked beautifully ;-). Btw, is it Win9x or NT/2000?

Jugoslav
0 Kudos
grtoro
Beginner
2,266 Views
Jugoslav,

Thanks for your help. I am using W98 SE. Two things I want to add:

a) The Ghostscript program works fine every time, even when I get the (apparently spurious) error messages. I am mainly concerned with memory leaks that may be occuring.

b) After seemingly harmless changes to dirName and other variables from "startp" that appear to be unused, I am finding that the errors occur only occasionaly (not consistently) after the first time.

This is probably a problem my program can live with, but I would like to resolve it, especially because of the possibility of memory leaks.

Thanks again,

Gabriel
0 Kudos
Reply