- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I want my Fortran program to check for internet connection and warn the user if not connected. I think I need to use the method GetConnectivity but can't find an example of this for use in Fortran. Apparently the API, InternetGetConnectedState is no longer recommended.
Any help or advice would be appreciated - manys thanks in advance.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@SoniaG ,
Re: ".. I think I need to use the method GetConnectivity but can't find an example of this for use in Fortran. ..," you may have seen this at the Microsoft site:
You'll notice the GetConnectivity - which is indeed Microsoft's recommended method in their so-called unmanaged programs (and which is what all Fortran apps are) on Windows - is a C++ class method of INetworkListManager that is invokable via COM. As such, you would either need to use Intel Fortran's COM interoperability module(s) or setup something yourself using C-Fortran interoperability. Both are a little more effort than I would be willing to undertake, so I would instead write a small extern "C" wrapper function in C++ like so: it's a one-time effort easier to manage I feel:
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <Netlistmgr.h>
#include <atlbase.h>
extern "C" int IsConnected(char *msg, size_t lenmsg)
{
int irc = 0;
CoInitialize(NULL);
{
CComPtr<INetworkListManager> pNLM;
HRESULT hr = CoCreateInstance(CLSID_NetworkListManager, NULL,
CLSCTX_ALL, __uuidof(INetworkListManager), (LPVOID*)&pNLM);
if (SUCCEEDED(hr))
{
NLM_CONNECTIVITY con = NLM_CONNECTIVITY_DISCONNECTED;
hr = pNLM->GetConnectivity(&con);
if SUCCEEDED(hr)
{
if (con & NLM_CONNECTIVITY_DISCONNECTED)
snprintf(msg, lenmsg, "%s\n", "Disconnected");
if (con & NLM_CONNECTIVITY_IPV4_NOTRAFFIC)
snprintf(msg, lenmsg, "%s\n", "IP4: No Traffic");
if (con & NLM_CONNECTIVITY_IPV6_NOTRAFFIC)
snprintf(msg, lenmsg, "%s\n", "IP6: No Traffic");
if (con & NLM_CONNECTIVITY_IPV4_INTERNET)
snprintf(msg, lenmsg, "%s\n", "IP4: Internet");
if (con & NLM_CONNECTIVITY_IPV4_LOCALNETWORK)
snprintf(msg, lenmsg, "%s\n", "IP4: Local");
if (con & NLM_CONNECTIVITY_IPV4_SUBNET)
snprintf(msg, lenmsg, "%s\n", "IP4: Subnet");
if (con & NLM_CONNECTIVITY_IPV6_INTERNET)
snprintf(msg, lenmsg, "%s\n", "IP6: Internet");
if (con & NLM_CONNECTIVITY_IPV6_LOCALNETWORK)
snprintf(msg, lenmsg, "%s\n", "IP6: Local");
if (con & NLM_CONNECTIVITY_IPV6_SUBNET)
snprintf(msg, lenmsg, "%s\n", "IP6: Subnet");
}
}
irc = (int)hr;
}
CoUninitialize();
return irc;
}
And setup an interface to it in Fortran like so, again a one-time effort:
module NetListMgr_m
use, intrinsic :: iso_c_binding, only : c_char, c_int, c_size_t
interface
function IsConnected( Msg, LenMsg ) result(r) bind(C, name="IsConnected" )
! int IsConnected(char *msg, size_t lenmsg);
import :: c_char, c_int, c_size_t
! Argument list
character(kind=c_char, len=1), intent(in) :: Msg(*)
integer(c_size_t), intent(in), value :: LenMsg
! Function result
integer(c_int) :: r
end function
end interface
end module
Then the following Fortran test program can make use of it:
program TestConnection
use, intrinsic :: iso_c_binding, only : c_char, c_size_t, c_int
use NetListMgr_m, only : IsConnected
character(kind=c_char, len=256) :: ConnectionState
integer(c_size_t) :: lens
integer(c_int) :: cstat
lens = int( len(ConnectionState), kind=kind(lens) )
cstat = IsConnected( ConnectionState, lens )
print *, "ctsat: ", cstat
print *, trim(ConnectionState)
end program
You can tuck away the above C function and the Fortran module code in a library (static or DLL) and use it in your Fortran programs - Visual Studio projects can make this easy as you may know.
From the command-line, for illustration purposes, you can expect the following behavior:
C:\Temp>cl /c /EHsc /W3 IsConnected.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.26.28806 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
IsConnected.cpp
C:\Temp>ifort /c /standard-semantics /warn:all /stand:f18 NetListMgr.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1.2 Build 20201208_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
C:\Temp>ifort /c /standard-semantics /warn:all /stand:f18 TestConnection.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1.2 Build 20201208_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
C:\Temp>link TestConnection.obj NetListMgr.obj IsConnected.obj /subsystem:console /out:TestConnection.exe
Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation. All rights reserved.
C:\Temp>TestConnection.exe
ctsat: 0
IP4: Internet
C:\Temp>
P.S.> Some of the above code is a bit more verbose than otherwise, but it's for the benefit of other readers also. Also, it's possible Intel Fortran provides some module procedures for this - I've not checked - but that will be compiler-specific. The above should work with any Fortran standard supporting compiler.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not quite the same thing but I use URLDownloadToFile to download a page from the web to a local file. A failure to get something that is known to exist could be indicative of no connection.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Experiment with EXECUTE_COMMAND_LINE with "ping -w 500 -n 1 yahoo.com>check.txt"
You should test to see if exitstat returns error code when ping fails, and in which case you need not check the check.txt for ping error.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is a rather interesting answer here from 2011 -- it should still work
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks @jimdempseyatthecove
I have written the following code but, although the command execution runs, I almost always get an estat of 1. My program is running in Windows and I am connected to the internet (it's a strong signal and not intermittant). I get similar results whether running in debug (Visual Studio) or in production.
If the code below looks ok, I assume there must be something else at play?
call execute_command_line("ping -w 500 -n 1 yahoo.com>check.txt",exitstat=estat,cmdstat=cstat,cmdmsg=cmsg)
if(cstat > 0) then
iret = messagebox(ghwndmain,'Command execution failed with error'//trim(cmsg)//char(0),'Check for internet connection'//char(0),mb_ok)
else if(cstat < 0) then
iret = messagebox(ghwndmain,'Command execution not supported'//trim(cmsg)//char(0),'Check for internet connection'//char(0),mb_ok)
else
write(cestat,'(I4)')estat
if(estat==0)then
iret = messagebox(ghwndmain,'Internet connection ok, estat ='//trim(cestat)//char(0),'Check for internet connection'//char(0),mb_ok)
else
iret = messagebox(ghwndmain,'No internet connection found, estat ='//trim(cestat)//char(0),'Check for internet connection'//char(0),mb_ok)
end if
end if
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What happens if you set the timeout to -w 5000?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@SoniaG ,
Re: ".. I think I need to use the method GetConnectivity but can't find an example of this for use in Fortran. ..," you may have seen this at the Microsoft site:
You'll notice the GetConnectivity - which is indeed Microsoft's recommended method in their so-called unmanaged programs (and which is what all Fortran apps are) on Windows - is a C++ class method of INetworkListManager that is invokable via COM. As such, you would either need to use Intel Fortran's COM interoperability module(s) or setup something yourself using C-Fortran interoperability. Both are a little more effort than I would be willing to undertake, so I would instead write a small extern "C" wrapper function in C++ like so: it's a one-time effort easier to manage I feel:
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <Netlistmgr.h>
#include <atlbase.h>
extern "C" int IsConnected(char *msg, size_t lenmsg)
{
int irc = 0;
CoInitialize(NULL);
{
CComPtr<INetworkListManager> pNLM;
HRESULT hr = CoCreateInstance(CLSID_NetworkListManager, NULL,
CLSCTX_ALL, __uuidof(INetworkListManager), (LPVOID*)&pNLM);
if (SUCCEEDED(hr))
{
NLM_CONNECTIVITY con = NLM_CONNECTIVITY_DISCONNECTED;
hr = pNLM->GetConnectivity(&con);
if SUCCEEDED(hr)
{
if (con & NLM_CONNECTIVITY_DISCONNECTED)
snprintf(msg, lenmsg, "%s\n", "Disconnected");
if (con & NLM_CONNECTIVITY_IPV4_NOTRAFFIC)
snprintf(msg, lenmsg, "%s\n", "IP4: No Traffic");
if (con & NLM_CONNECTIVITY_IPV6_NOTRAFFIC)
snprintf(msg, lenmsg, "%s\n", "IP6: No Traffic");
if (con & NLM_CONNECTIVITY_IPV4_INTERNET)
snprintf(msg, lenmsg, "%s\n", "IP4: Internet");
if (con & NLM_CONNECTIVITY_IPV4_LOCALNETWORK)
snprintf(msg, lenmsg, "%s\n", "IP4: Local");
if (con & NLM_CONNECTIVITY_IPV4_SUBNET)
snprintf(msg, lenmsg, "%s\n", "IP4: Subnet");
if (con & NLM_CONNECTIVITY_IPV6_INTERNET)
snprintf(msg, lenmsg, "%s\n", "IP6: Internet");
if (con & NLM_CONNECTIVITY_IPV6_LOCALNETWORK)
snprintf(msg, lenmsg, "%s\n", "IP6: Local");
if (con & NLM_CONNECTIVITY_IPV6_SUBNET)
snprintf(msg, lenmsg, "%s\n", "IP6: Subnet");
}
}
irc = (int)hr;
}
CoUninitialize();
return irc;
}
And setup an interface to it in Fortran like so, again a one-time effort:
module NetListMgr_m
use, intrinsic :: iso_c_binding, only : c_char, c_int, c_size_t
interface
function IsConnected( Msg, LenMsg ) result(r) bind(C, name="IsConnected" )
! int IsConnected(char *msg, size_t lenmsg);
import :: c_char, c_int, c_size_t
! Argument list
character(kind=c_char, len=1), intent(in) :: Msg(*)
integer(c_size_t), intent(in), value :: LenMsg
! Function result
integer(c_int) :: r
end function
end interface
end module
Then the following Fortran test program can make use of it:
program TestConnection
use, intrinsic :: iso_c_binding, only : c_char, c_size_t, c_int
use NetListMgr_m, only : IsConnected
character(kind=c_char, len=256) :: ConnectionState
integer(c_size_t) :: lens
integer(c_int) :: cstat
lens = int( len(ConnectionState), kind=kind(lens) )
cstat = IsConnected( ConnectionState, lens )
print *, "ctsat: ", cstat
print *, trim(ConnectionState)
end program
You can tuck away the above C function and the Fortran module code in a library (static or DLL) and use it in your Fortran programs - Visual Studio projects can make this easy as you may know.
From the command-line, for illustration purposes, you can expect the following behavior:
C:\Temp>cl /c /EHsc /W3 IsConnected.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.26.28806 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
IsConnected.cpp
C:\Temp>ifort /c /standard-semantics /warn:all /stand:f18 NetListMgr.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1.2 Build 20201208_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
C:\Temp>ifort /c /standard-semantics /warn:all /stand:f18 TestConnection.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1.2 Build 20201208_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
C:\Temp>link TestConnection.obj NetListMgr.obj IsConnected.obj /subsystem:console /out:TestConnection.exe
Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation. All rights reserved.
C:\Temp>TestConnection.exe
ctsat: 0
IP4: Internet
C:\Temp>
P.S.> Some of the above code is a bit more verbose than otherwise, but it's for the benefit of other readers also. Also, it's possible Intel Fortran provides some module procedures for this - I've not checked - but that will be compiler-specific. The above should work with any Fortran standard supporting compiler.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sonia:
FortranFan's method is as good as it gets, I would adopt this one and stop searching.
- Tags:
- SOnia

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page