Frank,
You are doing what you should do by using execute_command_line, but it will launch a console every time it is called if your program doesn't already have a console window. There's no pure-Fortran solution for this issue on Windows, but it's relatively simple to get around using a simple C file added to your project.
I've written a short C routine, LaunchExecutable, that uses the Windows API to launch an arbitrary program. The C routine is in this file:
launch.c:
#include <windows.h>
int LaunchExecutable(char *exe, int wait)
{
SECURITY_ATTRIBUTES secattr;
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL bSuccess;
/* Open up some pipes */
ZeroMemory(&secattr, sizeof(SECURITY_ATTRIBUTES));
secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
secattr.lpSecurityDescriptor = NULL;
secattr.bInheritHandle = TRUE;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWDEFAULT;
bSuccess = CreateProcess(NULL, /* lpApplicationName */
exe, /* lpCommandLine */
NULL, /* lpProcessAttributes */
NULL, /* lpThreadAttributes */
TRUE, /* bInheritHandles */
0, /* dwCreationFlags */
NULL, /* lpEnvironment */
NULL, /* lpCurrentDirectory */
&si, /* lpStartupInfo */
&pi); /* lpProcessInformation */
if(!bSuccess)
return GetLastError();
if(wait)
WaitForSingleObject(pi.hProcess, INFINITE);
return ERROR_SUCCESS;
}
The above routine, though, needs a Fortran wrapper to work properly. My Fortran module, launcher, contains one routine, LaunchWindow, that implements the necessary Fortran wrapper:
launchf.f90:
module launcher
implicit none
private
public::LaunchWindow
contains
subroutine LaunchWindow(exe, wait, status)
use iso_c_binding
implicit none
character(*)::exe
logical, optional, intent(in)::wait
integer, optional, intent(out)::status
integer::internal_wait
integer::internal_ret
! For conversion to a C character array
integer::i
character(kind=c_char), dimension(:), allocatable::internal_exe
interface
function LaunchExecutable(exe, wait) bind(c, name="LaunchExecutable")
use iso_c_binding
integer(kind=c_int)::LaunchExecutable
character(kind=c_char)::exe
integer(kind=c_int), value::wait
end function LaunchExecutable
end interface
internal_wait = 0
if(present(wait)) then
if(wait) then
internal_wait = 1
else
internal_wait = 0
end if
end if
allocate(internal_exe(len_trim(exe)+1))
internal_exe = C_NULL_CHAR
do i=1,len_trim(exe)
internal_exe(i) = exe(i:i)
end do
internal_ret = LaunchExecutable(internal_exe(1), internal_wait)
if(present(status)) then
status = internal_ret
end if
deallocate(internal_exe)
end subroutine LaunchWindow
end module launcher
This routine takes a string with the full path to the executable. If the executable is located within the current working directory, you probably wouldn't need the full path. It has two optional arguments, wait which is a logical that reflects whether the routine should wait until the called process completes before returning, and status which returns any error codes that may have been returned by the call (0 means success).
As a simple example, here's a Fortran program that actually calls the routine:
hello.f90:
program helloworld
use launcher
implicit none
integer::i
CALL LaunchWindow("C:\Windows\System32\notepad.exe", status=i, wait=.FALSE.)
end program helloworld
The above launches Notepad and exits immediately without ever opening a console window.
Let me know if the above works for you. I'll be happy to update any code based on any requests.
Jeff Armstrong
Approximatrix, LLC