check whether Internet connection is available with C# - c#

What is the easiest way to check whether internet connection is available programatically?
EDIT:
As suggested I tried using the following method, but it is always returning true.
[Flags]
enum InternetConnectionState : int
{
INTERNET_CONNECTION_MODEM = 0x1,
INTERNET_CONNECTION_LAN = 0x2,
INTERNET_CONNECTION_PROXY = 0x4,
INTERNET_RAS_INSTALLED = 0x10,
INTERNET_CONNECTION_OFFLINE = 0x20,
INTERNET_CONNECTION_CONFIGURED = 0x40
}
class Program
{
[DllImport("WININET", CharSet = CharSet.Auto)]
static extern bool InternetGetConnectedState(ref InternetConnectionState lpdwFlags, int dwReserved);
static void Main(string[] args)
{
InternetConnectionState flags = 0;
bool isConnected = InternetGetConnectedState(ref flags, 0);
Console.WriteLine(isConnected);
//Console.WriteLine(flags);
Console.ReadKey();
}
}
Additional Info (if it helps): I access internet over a shared wifi network.

Here is the Windows API you can call into. It's in wininet.dll and called InternetGetConnectedState.
using System;
using System.Runtime;
using System.Runtime.InteropServices;
public class InternetCS
{
//Creating the extern function...
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState( out int Description, int ReservedValue );
//Creating a function that uses the API function...
public static bool IsConnectedToInternet( )
{
int Desc ;
return InternetGetConnectedState( out Desc, 0 ) ;
}
}

here is the best solution I found so far:
public static bool isConnected()
{
try
{
string myAddress = "www.google.com";
IPAddress[] addresslist = Dns.GetHostAddresses(myAddress);
if (addresslist[0].ToString().Length > 6)
{
return true;
}
else
return false;
}
catch
{
return false;
}
}
usage:
if(isConnected())
{
//im connected to the internet
}
else
{
//not connected
}

Microsoft windows vista and 7 use NCSI (Network Connectivity Status Indicator) technic:
NCSI performs a DNS lookup on www.msftncsi.com, then requests http://www.msftncsi.com/ncsi.txt. This file is a plain-text file and contains only the text 'Microsoft NCSI'.
NCSI sends a DNS lookup request for dns.msftncsi.com. This DNS address should resolve to 131.107.255.255. If the address does not match, then it is assumed that the internet connection is not functioning correctly.

You can check for a network connection using this in .NET 2.0+
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
This will probably just return true for local networks, so it may not work for you.

This is a question where the answer really is "it depends". Because it depends on why you want to check and for what kind of connectivity? Do you want to be able to access certain websites/services over http? Send smtp mail? Do dns lookups?
Using a combination of the previous answers is probably the way to go - first use the wininet api from colithium's answer to check if a connection of any kind is available.
If it is, try a couple of dns lookups (see System.Net.Dns ) for either the resources you're interested in or some popular big websites (google, altavista, compuserve, etc...).
Next, you can try pinging (see Roger Willcocks' answer) and/or establishing a socket connection to the same sites. Note that a failed ping could just mean that firewall rules don't allow you to ping.
If you can be more specific as to why you want to check it will be easier to provide an answer that covers your requirements...

Easiest way is to probably check if they can download a file from the web that you know is available. Use the following code to download google's homepage.
WebClient Client = new WebClient ();
String Response;
Response = Client.DownloadString("http://www.google.com");
You should probably wrap that in a Try .... Catch to catch the exception that is thrown when it can't establish a connection.

Network Awareness in Windows XP
Network Awareness in Windows Vista and Windows 7
Of course this does not guarantee the web site you plan to visit is not blocked by cooperative firewall rules, the API just checking if a pre-defined web site is reachable.

There are some other options too.
The InfoPath library exposes the "IsDestinationReachable" method, which is a wrapper for the Win API method of the same name. (Looks like Vista doesn't support it)
However, I believe from the Docs that it depends on something like PING, so not necessarily a good test.
Vista + say use the "Network List Manager"
#colithium Google might not be down, but things can also fail out if the DNS lokup interval exceeds the timeout. Not uncommon at home here in NZ, first try fails, second succeeds because the data has propogated back to the ISP DNS or your router cache by the time the second request is done.

Alternatively you can use DNS lookup to check internet connectivity. This method is faster than Ping method.
public static bool DnsTest()
{
try
{
System.Net.IPHostEntry ipHe =
System.Net.Dns.GetHostByName("www.google.com");
return true;
}
catch
{
return false;
}
}

Related

Easy and reasonable secure way to identify a specific network

We like to enable some hidden features of our software only if it is run inside of the company network. The key requirements are:
no need for a third party library outside of DotNet 4.5.1
easy to implement (should not be more than some dozens of lines .. I don't want to reimplement a crypto library)
It should be reasonable safe:
at least: hard to reverse engineer
at best: "impossible" to break even with read-access to the source code
low maintenance overhead
Win2012-Server is available for installation of additional software (open source or own implementation prefered - server can be assumed to be safe)
What I have thought about:
Check if a specific PC is available with a known MAC or IP (current implementation, not really secure and some other flaws)
Test, if a service is available on a specific response (i.e. I send 'Hello' to MyServer:12345 - server responses with 'World')
Similar to 2nd but a more complex challenge (i.e. send a seed for a RNG to the server, verify the response)
Set up an apache with HTTPS and verify the certificate
If you use ActiveDirectory, you could add a reference to the System.DirectoryServices namespace and check
ActiveDirectorySite currentSite = ActiveDirectorySite.GetComputerSite();
then you can get a bit of information from the currentSite object and check against that. That's how I enable/disable features of an application I'm developing currently.
I also grab:
var client = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in client.AddressList)
{
if(ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
ipAddress = ip;
}
}
Which you can check to make sure the client is connected with the proper protocol.
I've choosen the last option: Set up a webserver in the intranet and verify the certificate.
It was easier than expected. There are enough tutorials for setting up an apache with https for every supported OS. The self-signed certificate have a lifetime of 9999 days - should be okay until 2042. The C#-part is also reasonable small:
private static bool m_isHomeLocation = false;
public static bool IsHomeLocation
{
get
{
if (m_isHomeLocation)
return true;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://yourLicenseServer:yourConfiguredPort");
request.ServerCertificateValidationCallback += ((s, certificate, chain, sslPolicyErrors) => true);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Close();
var thumbprint = new X509Certificate2(request.ServicePoint.Certificate).Thumbprint;
m_isHomeLocation = (thumbprint == "WhateverThumbprintYourCertificateHave");
}
catch
{
// pass - maybe next time
}
return m_isHomeLocation;
}
}

Change proxy setting for IE instance using Watin

I know that I can change the computers global proxy setting, Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings, to affect IE instances created using Watin.
But is there any way to intercept requests made by the IE browsers and run them through a proxy? My goal is to run multiple instances of IE, each with its own proxy, which isn't possible with my current solution above.
WatiN IE creates multiple ProcessIDs (single instance IE creates multiple process ids). in order to overwrite proxy settings just for WatiN by using Fiddler Core we need to get all child process ids which are created by WatiN IE. Helper class can be found here PInvoke: Getting all child handles of window – Svett Ralchev class. And then we check all process ids inside the BeforeRequest event and wait for watin process id to overwrite proxy settings.
private void FiddlerApplication_BeforeRequest(Session sess)
{
//Debug.WriteLine("FiddlerApplication_BeforeRequest: " + sess.LocalProcessID.ToString());
if (WatinIEprocessHolder.ContainsKey(sess.LocalProcessID))
{
//see http://stackoverflow.com/questions/14284256/how-to-manually-set-upstream-proxy-for-fiddler-core
sess["X-OverrideGateway"] = WatinIEprocessHolder[sess.LocalProcessID];
}
}
Working Test Application can be downloaded here http://www.rentanadviser.com/downloads/WatiN-2.1.0.1196.zip
Test results with different anonymous proxy below. (ipaddress=browser.Text)
Process Ids:3852,7852,, Your IP address: 119.46.110.17, Proxy:119.46.110.17:8080
Process Ids:2508,6948,, Your IP address: 178.21.112.27, Proxy:178.21.112.27:3128
Process Ids:1348,1368,, Your IP address: 122.96.59.107, Proxy:122.96.59.107:83
Process Ids:7152,5104,, Your IP address: 136.0.16.217, Proxy:136.0.16.217:3127
Process Ids:4128,3480,, Your IP address: 198.52.199.152, Proxy:198.52.199.152:7808
Process Ids:2036,7844,, Your IP address: 122.96.59.107, Proxy:122.96.59.107:82
Sample code:
private void this_FormClosing(object sender, FormClosingEventArgs e)
{
StopFiddler();
}
private void Form1_Load(object sender, EventArgs e)
{
this.FormClosing += this_FormClosing;
ProxyHolder = new List<string>();
ProxyHolder.Add("119.46.110.17:8080");
ProxyHolder.Add("178.21.112.27:3128");
ProxyHolder.Add("122.96.59.107:83");
ProxyHolder.Add("136.0.16.217:3127");
ProxyHolder.Add("198.52.199.152:7808");
ProxyHolder.Add("122.96.59.107:82");
StartFiddler();
System.Threading.Thread.Sleep(500);
for (var i = 0; i < ProxyHolder.Count; i++)
{
WhatIsMyIpThroughProxy(ProxyHolder[i]);
Application.DoEvents();
System.Threading.Thread.Sleep(500);
}
//WhatIsMyIpThroughProxy();
}
private Dictionary<int, string> WatinIEprocessHolder = new Dictionary<int, string>();
private List<string> ProxyHolder = null;
public void WhatIsMyIpThroughProxy(string ProxyIPandPort)
{
using (var browser = new IE(true))// we should not navigate now. Because we need process ids.
{
WindowHandleInfo ChildHandles = new WindowHandleInfo(browser.hWnd);
foreach (var cHandle in ChildHandles.GetAllChildHandles())
{
int pid = new WatiN.Core.Native.Windows.Window(cHandle).ProcessID;
if (WatinIEprocessHolder.ContainsKey(pid) == false)
WatinIEprocessHolder.Add(pid, ProxyIPandPort);
}
System.Text.StringBuilder processIDs = new System.Text.StringBuilder();
foreach (var k in WatinIEprocessHolder.Keys)
{
processIDs.Append(k.ToString() + ",");
//Debug.WriteLine(string.Format("{0}:{1}", k, WatinIEprocessHolder[k]));
}
//we got the process ids above. Navigate now.
browser.GoTo("http://www.rentanadviser.com/en/common/tools.ashx?action=whatismyip");
browser.WaitForComplete();
WatinIEprocessHolder.Clear();
System.Net.IPAddress ip;
if (System.Net.IPAddress.TryParse(browser.Text, out ip))
{
Debug.WriteLine(string.Format("Process Ids:{0}, Your IP address: {1}, Proxy:{2}", processIDs.ToString(), browser.Text, ProxyIPandPort));
}
else
{
Debug.WriteLine(string.Format("Process Ids:{0}, Your IP address: {1}, Proxy:{2}", processIDs.ToString(), "Failed", ProxyIPandPort));
}
}
}
private void StartFiddler()
{
FiddlerApplication.BeforeRequest += FiddlerApplication_BeforeRequest;
FiddlerApplication.Startup(8888, true, true, true);
}
private void StopFiddler()
{
FiddlerApplication.BeforeRequest -= FiddlerApplication_BeforeRequest;
if (FiddlerApplication.IsStarted())
{
FiddlerApplication.Shutdown();
}
}
private void FiddlerApplication_BeforeRequest(Session sess)
{
//Debug.WriteLine("FiddlerApplication_BeforeRequest: " + sess.LocalProcessID.ToString());
if (WatinIEprocessHolder.ContainsKey(sess.LocalProcessID))
{
//see http://stackoverflow.com/questions/14284256/how-to-manually-set-upstream-proxy-for-fiddler-core
sess["X-OverrideGateway"] = WatinIEprocessHolder[sess.LocalProcessID];
}
}
I've created an app called Process Proxifier which uses FiddlerCore to add proxy settings to the Windows applications dynamically. You can find its full source code here: https://processproxifier.codeplex.com/
Also I should mention that this solution is limited to target processes with system's default "CERN" proxy setting (which is pointed at Fiddler/FiddlerCore).
It's not possible to do that with IE or even with WebBrowser (it's just an instance of IE).
But you can manipute WebBrowser behavior to achieve your desired feature.
It's possible to write your custom WebBrowser which fetched data by sending your custom WebRequest that contain your different proxy.
How to load web browser with web response
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://example.com");
webRequest.Proxy = new WebProxy(host, port);
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
Stream receiveStream = response.GetResponseStream();
WebBrowser webBrowser = new WebBrowser();
webBrowser.DocumentStream = receiveStream;
WebRequest.Proxy
I know you are looking for an alternative solution without using the computers global proxy setting but I thought of adding this here so others who don't have this constraint know about it.
The solution was on your question - The Windows Registry.
It is simple to change the proxy settings globally at runtime, you need to change the registry keys you are interested in using the Microsoft.Win32.Registry class in the Microsoft.Win32 namespace.
You can find MSDN documentation for this here: http://msdn.microsoft.com/en-us/library/microsoft.win32.registry(v=vs.110).aspx
See below an example of how to do this.
RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Your key", true);
myKey.SetValue("My String Value", "Test Value", RegistryValueKind.String);
Now to change proxy settings on the box you need to change or create the right proxy registry keys you can find all the available keys at:
MSDN Documentation - 2.2.1.10 Internet Settings.
Below is a few of the keys you need to set. Each version of IE has their own keys but the ones below are identical to all browsers.
UseProxyServer
REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyEnable
ProxyServerAndPort
REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer
ProxyOverride
REG_SZ
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyOverride
HTTP1_1ThroughProxy
REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\HTTP1_1ThroughProxy
User Specific
Please bear in mind these are Current user registry entries so you may need to set them in the context of the windows identity. Also the simplest way to see what should be the values for these keys is to apply the proxy changes on the Internet Settings dialog and check them on RegEdit.exe.
Create user automatically
This is your saving grace here because you can run your process for watin on a local windows account with the settings that way you dont need to change your own proxy settings.
You can then have one user called WatinUser that the proxy settings are set against you can automate the creation of this user using the System.DirectoryServices.AccountManagement Namespace classses.
See examples here at SO: create local user account
There are products like Proxifier that let you setup rules to route traffic to different proxies based on application names, IP addresses, hostnames and port numbers. This would not let you use different proxies for multiple IE processes, but if those processes were accessing different URLs you could route the traffic through separate proxy servers. Proxifier works using the WinSocks stack, similar to what many antivirus use, and it is transparent to the application layer.
Another suggestion is to write your own web request interceptor/proxy server that will grab proxy server info from requested url and forward normalized url to the real proxy server.
for e.g. from watin you launch url "someurl?ProxyServer=10.10.10.12" now this will be intercepted by your own proxy server and it will use the proxy server param to redirect requested url i.e. "someurl" to 10.10.10.12 your proxy server implementation can set proxy details at run time and fetch the results from your server using dynamic proxy.
I hope it makes some sense.

How do I check the network connection win the fatest way?

I'm developing an application for Honeywell Dolphin 6100, a mobile computer with a barcode scanner that uses Windows CE 5.0 like OS.
I want to use a function which can check the network connection existence, I tried to use the code below but its too slow.
public static bool CheckForInternetConnection()
{
string url = "http://www.Microsoft.com/";
try
{
System.Net.WebRequest myRequest = System.Net.WebRequest.Create(url);
System.Net.WebResponse myResponse = myRequest.GetResponse();
}
catch (System.Net.WebException)
{
return false;
}
return true;
}
Any one have an idea for a faster way to do that. I mention that I'm working with VS2008 on win7
Since you're not doing anything with the content of the response, there's really no reason to request it, and wait for the network transfer of all that data. You might try setting myRequest.Method = "HEAD", which will just return headers (assuming the web server supports it), but obviously still verify that you can communicate with the remote web server.
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.method.aspx
Assuming availability on your version of the .net runtime, you can call the static System.Net.NetworkInformation.GetIsNetworkAvailable() method. There are scenarios where that'll return true and you won't be able to route to the outside world, but it'll tell you whether your device has a network interface that's marked as being up.

How to check if a web service is up and running without using ping?

How can i check if a method in a web service is working fine or not ? I cannot use ping. I still want to check any kind of method being invoked from the web service by the client. I know it is difficult to generalize but there should be some way.
I use this method and it works fine :
public bool IsAddressAvailable(string address)
{
try
{
System.Net.WebClient client = new WebClient();
client.DownloadData(address);
return true;
}
catch
{
return false;
}
}
The only way to know if a web service method is working "fine" is to call the method and then to evaluate whether the result is "fine". If you want to keep a record of "fine" vs. time, then you can log the result of the evaluation.
There's no more general way to do this that makes any sense. Consider:
You could have code that creates an HTTP connection to the service endpoint, but success doesn't tell you whether the service will immediately throw an exception as soon as you send it any message.
You could connect and send it an invalid message, but that doesn't tell you much.
You could connect and send it a valid message, then check the result to ensure that it is valid. That will give you a pretty good idea that when a real client calls the service immediately afterwards, the real client should expect a valid result.
Unless the service takes that as an opportunity to crash, just to spite you!
The best technique would be to use WCF tracing (possibly with message-level tracing) to log what actually happens with the service, good or bad. A human can then look at the logs to see if they are "fine".
Powershell is by far an easy way to 'ping' a webservice endpoint.
Use the following expression:
Test-NetConnection -Port 4408 -ComputerName 192.168.134.1
Here is a failure response for a port that does not exist or is not listening;
WARNING: TCP connect to 192.168.134.1:4408 failed
ComputerName : 192.168.134.1
RemoteAddress : 192.168.134.1
RemotePort : 4408
InterfaceAlias : Ethernet0
SourceAddress : 192.168.134.1
PingSucceeded : True
PingReplyDetails (RTT) : 0 ms
TcpTestSucceeded : False
Here is a success result if the address/port is listening and accessible:
ComputerName : 192.168.134.1
RemoteAddress : 192.168.134.1
RemotePort : 4407
InterfaceAlias : Ethernet0
SourceAddress : 192.168.134.1
TcpTestSucceeded : True
just use try catch inside the method of your webservice and log exceptions to a log file or to the event log.
Example:
[OperationContract]
public bool isGUID(string input)
{
bool functionReturnValue = false;
try
{
Guid guid;
functionReturnValue = Guid.TryParse(input, guid);
}
catch (Exception ex)
{
Log.WriteServerErrorLog(ex);
}
return functionReturnValue;
}
You don't need to ping the webservice, but instead ping the server with a watchdog service or something. There is no need to "ping" the webservice. I also think you don't need to do this anyway.
Either your webservice works or it doesn't because of bad code.
You may try curl. It's a Linux tool, should be there in Cygwin too.
$ curl http://google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
here.
</BODY></HTML>
There are lots of options; examples can be found in the 'net.
You can write your self a little tool or windows service or whatever you need then look at these 2 articles:
C#: How to programmatically check a web service is up and running?
check to if web-service is up and running - efficiently
EDIT:
This was my implementation in a similar scenario where I need to know if an external service still exists every time before the call is made:
bool IsExternalServiceRunning
{
get
{
bool isRunning = false;
try
{
var endpoint = new ServiceClient();
var serviceUri = endpoint.Endpoint.Address.Uri;
var request = (HttpWebRequest)WebRequest.Create(serviceUri);
request.Timeout = 1000000;
var response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
isRunning = true;
}
#region
catch (Exception ex)
{
// Handle error
}
#endregion
return isRunning;
}
}
As I see it, you have 2 options:
If you can access the server it is running on, Log every call (and exceptions thrown). Read the log file with a soft like baretail that updates as the file is being written.
If you can't access the server, then you have to make the webservice write that log remotely to another computer you have access to.
Popular loggers have this functionality built in. (Log4Net, ...)
You could also use tracing.
http://msdn.microsoft.com/en-us/library/ms732023.aspx
http://msdn.microsoft.com/en-us/library/ms733025.aspx

Detect If Offline - in C# WebBrowser component?

We're working on a wrapped WebBrowser component. We'd like to display one page (e.g. oursite.com/thispage.html) if the user is online and another page (e.g. C:\somewhere\thispage_offline.html) if the user is offline. I'm able to to properly display both pages, but my issue is detecting the online/offline status.
I tried
WebBrowser.IsOffline; however it seems that only relays the Offline Mode status, not whether or not the computer is actually able to reach the internet.
Is there a way to detect this from the WebBrowser component? Is there a way at all?
Thanks for all your help!
The simplest way to check for internet connectivity is to ping your server.
Try this code:
public static bool IsOnline() {
var pinger = new Ping();
try {
return pinger.Send("oursite.com").Status == IPStatus.Success;
} catch(SocketException) { return false; } catch(PingException) { return false; }
}
Alternatively, you can try using the WebRequest class to send a request to a simple page on your site and see whether it succeeds. This is a better option because it will also make sure that IIS (or Apache) is running on the server.
What if you just used the Ping class to see if the site is available?

Categories

Resources