Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Hiding Console Window

dannycat
New Contributor I
1,469 Views
I have a procedure within a FORTRAN Windows application that has the potential to loop several hundred times and during each loop I use the SYSTEM('Batchfile.bat') function to run an external executable program. Currently when the program runs a console window is displayed every time this function is called and this can be a bit annoying for the user. Does anyone know of analternative way to execute a program from within a FORTRAN (Windows) application where you can prevent the window being displayed. I looked into CreateProcess API function but the documentation is a bit confusing so I'm not sure if this is the way forward.

Any help on this will be much appreciated.
0 Kudos
6 Replies
Arjen_Markus
Honored Contributor II
1,469 Views
Have you tried with:

call system( "start /b mybatch" )

(help start will inform you about the other options the command has) Not sure it does work, but it seems a likely possibility.

Regards,

Arjen
0 Kudos
Steven_L_Intel1
Employee
1,469 Views
ShellExecute is easy to use. Do you need to wait for the program to complete? If so, then CreateProcess will be needed.
0 Kudos
dannycat
New Contributor I
1,469 Views
Steve,
As I need it to wait for process to finish Idecided to use CreateProcess. I've managed to get it to work apart from waiting. See the code below:

logical function w32_CreateProcess(exefile, infile)

!**************************************************************

! Use Crate Process API to execute external program

!**************************************************************

use dfwin

! Arguments

character*(*),intent(in) :: exefile

character*(*),intent(in) :: infile

! Local variables

character*255 :: cmd_line

Type(T_Process_Information) :: pi

type(T_StartupInfo) :: si

type(T_SECURITY_ATTRIBUTES) :: sao,sap,sat

integer(DWORD) :: iret

integer(HANDLE) :: hfile,err

! Initialise

w32_CreateProcess = .false.

! Set up command line

cmd_line = trim(exefile)

! proc sec attributes

sap%nLength = sizeof(sap)

sap%lpSecurityDescriptor = NULL

sap%bInheritHandle = 1

! thread sec attributes

sat%nLength = sizeof(sat)

sat%lpSecurityDescriptor = NULL

sat%bInheritHandle = 1

! set attributes for the error file

sao%nLength = sizeof(sao)

sao%lpSecurityDescriptor = NULL

sao%bInheritHandle = 1

! Open File for reading

hFile = CreateFile (trim(infile)//char(0), GENERIC_READ, &

FILE_SHARE_READ, sao,OPEN_EXISTING, &

FILE_FLAG_SEQUENTIAL_SCAN, NULL)

if (hFile.eq.INVALID_HANDLE_VALUE) then

call grp_message("ERROR: Creating File err.log")

return

end if

err = CreateFile('err.log'C, &

ior(GENERIC_WRITE,GENERIC_READ), &

ior(FILE_SHARE_READ,FILE_SHARE_WRITE), &

sao, &

CREATE_ALWAYS, &

FILE_ATTRIBUTE_NORMAL,NULL)

if(err.eq.INVALID_HANDLE_VALUE) then

call grp_message("ERROR: Creating File err.log")

return

endif

! Set up Startup Data structure

si%cb = sizeof(si)

si%lpReserved = NULL

si%lpDesktop = NULL

si%lpTitle = NULL

si%dwX = NULL

si%dwY = NULL

si%dwXSize = NULL

si%dwYSize = NULL

si%dwXCountChars = NULL

si%dwYCountChars = NULL

si%dwFillAttribute = NULL

si%dwFlags = ior(STARTF_USESHOWWINDOW,STARTF_USESTDHANDLES)

si%wShowWindow = SW_HIDE

si%cbReserved2 = 0

si%lpReserved2 = NULL

si%hStdInput = hFile

si%hStdOutput = err

si%hStdError = err

! Create Process

iret = CreateProcess(NULL, & ! No module name (use command line)

trim(cmd_line)//char(0), & ! Full Command Line

loc(sap), & ! Process handle not inheritable

loc(sat), & ! Thread handle not inheritable

TRUE, & ! Set handle inheritance to FALSE

ior(NORMAL_PRIORITY_CLASS,CREATE_NO_WINDOW), & ! No creation flags

NULL, & ! Use parent's environment block

NULL, & ! Use parent's starting directory

loc(si), & ! Pointer to STARTUPINFO structure

loc(pi)) ! Pointer to PROCESS_INFORMATION structure

if(iret.ne.0) then

! wait until the process is done

iret = WaitForInputIdle(pi%hProcess,INFINITE) ! time-out interval in milliseconds

iret = CloseHandle(pi%hProcess)

iret = CloseHandle(pi%hThread)

iret = CloseHandle(err)

iret = CloseHandle(hfile)

w32_CreateProcess = .true.

endif

return

end function

This function assigns the input ($CONIN)and output ($CONOUT) using CreateFile
I don't want to put sleepQQ(time) is the code as this is messy and will slow down the process too much if a time high enough to cover fluctuations in server responses etc is used.

The WaitForInputIdle seems to be ignored which the documentation says is the case when running as a GUI process though it does explain what these are. (None consule perhaps).

What do I need to do to resolve this?

0 Kudos
Steven_L_Intel1
Employee
1,469 Views
WaitForSingleObject can be used to wait for process completion. See here.
0 Kudos
dannycat
New Contributor I
1,469 Views
Ah yes, thats done the trick! I've replaced WaitForInputIdle with WaitForSingleObject (and moved the CloseHandle functions outside the if(CreateProcess... block as they need to be called even when CreateProcess fails.

Thanks Steve
0 Kudos
Geoff_Hall
Beginner
1,469 Views
Hey thanks for your post dannycat. Your code helped by to solve a different, but related, problem I was having with reassigning std handles in CreateProcess :)

Cheers, Geoff
0 Kudos
Reply