Tim Hibbard

CEO for EnGraph software
posts - 626, comments - 1586, trackbacks - 459

My Links

News



Add to Google

Twitter












Tag Cloud

Article Categories

Archives

Post Categories

Image Galleries

EnGraph Blogs

Links

Other

Roll

C# code to maintain VPN connection programatically

Windows has pretty good VPN management.  It's pretty good at redialing the connection when the connection is dropped, and for the most part it works.

However, sometimes it thinks it connected to the VPN when it's really not, and it doesn't validate the connection to a specific internal IP.  I needed something that was a bit more robust and could disconnect and reconnect if it couldn't see a specific IP.

This class takes a VPN connection name and an IP to ping and will use rasphone.exe to connect and NetworkInformation.Ping to verify connectivity.  Every 15 seconds, it checks connectivity and redials as needed.

Obviously, the VPN has to have the authentication saved, and redial attempts set to zero.

using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace VPNManager { /// <summary> /// Class to maintain connectivity to a specific VPN connection /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public class VPN { #region --Const-- /// <summary> /// Where the rasphone.exe lives /// </summary> private const string VPNPROCESS = "C:\\WINDOWS\\system32\\rasphone.exe"; #endregion #region --Fields-- /// <summary> /// Internal variable for VPNConnectionName /// </summary> private string _VPNConnectionName = ""; /// <summary> /// Internal variable for IPToPing /// </summary> private string _IPToPing = ""; /// <summary> /// Internal variable for IsConnected /// </summary> private bool _isConnected = false; /// <summary> /// Timer that manages the Manage function /// </summary> private System.Timers.Timer MonitorTimer; /// <summary> /// Bool to flag if the system is currently checking for network validity /// </summary> private bool _isChecking = false; /// <summary> /// Bool to flag if the system is currently in a Manage loop /// </summary> private bool _isManaging = false; #endregion #region --Events-- public delegate void PingingHandler(); public delegate void ConnectingHandler(); public delegate void DisconnectingHandler(); public delegate void IdleHandler(); public delegate void ConnectionStatusChangedHandler(bool Connected); /// <summary> /// Fires when validating connectivity /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public event PingingHandler Pinging; /// <summary> /// Fired when it is trying to connect to the VPN /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public event ConnectingHandler Connecting; /// <summary> /// Fired when it is trying to disconnect from the VPN /// </summary> public event DisconnectingHandler Disconnecting; /// <summary> /// Fired when it is done working for the moment /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public event IdleHandler Idle; /// <summary> /// Fired when the IsConnected Property changes /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public event ConnectionStatusChangedHandler ConnectionStatusChanged; /// <summary> /// Call to raise Pinging event /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> protected void OnPinging() { if (Pinging != null) { Pinging(); } } /// <summary> /// Call to raise Connecting event /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> protected void OnConnecting() { if (Connecting != null) { Connecting(); } } /// <summary> /// Call to raise Disconnecting event /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> protected void OnDisconnecting() { if (Disconnecting != null) { Disconnecting(); } } /// <summary> /// Call to raise Idle event /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> protected void OnIdle() { if (Idle != null) { Idle(); } } /// <summary> /// Call to raise ConnectionStatusChanged event /// </summary> /// <param name="Connected">If connected to network</param> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> protected void OnConnectionStatusChanged(bool Connected) { if (ConnectionStatusChanged != null) { ConnectionStatusChanged(Connected); } } #endregion #region --Properties-- /// <summary> /// Returns if you are connected to the network /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public bool IsConnected { get { return _isConnected; } } /// <summary> /// IP to ping to validate connectivity /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public string IPToPing { get { return _IPToPing; } set { _IPToPing = value; } } /// <summary> /// Name of VPN connection as seen in network connections (not case sensitive) /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public string VPNConnectionName { get { return _VPNConnectionName; } set { _VPNConnectionName = value; } } #endregion #region --Private Methods-- /// <summary> /// Pings the provided IP to validate connection /// </summary> /// <returns>True if you are connected</returns> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public bool TestConnection() { bool RV = false; _isChecking = true; try { OnPinging(); System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping(); if (ping.Send(_IPToPing).Status == System.Net.NetworkInformation.IPStatus.Success) { RV = true; } else { RV = false; } ping = null; if (RV != _isConnected) { _isConnected = RV; OnConnectionStatusChanged(_isConnected); } OnIdle(); } catch (Exception Ex) { Debug.Assert(false, Ex.ToString()); RV = false; OnIdle(); } _isChecking = false; return RV; } /// <summary> /// Shells the command to connect to the VPN /// </summary> /// <returns>True if connected</returns> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> private bool ConnectToVPN() { bool RV = false; try { OnConnecting(); Process.Start(VPNPROCESS," -d " + _VPNConnectionName); System.Windows.Forms.Application.DoEvents(); System.Threading.Thread.Sleep(5000); System.Windows.Forms.Application.DoEvents(); RV = true; OnIdle(); } catch (Exception Ex) { Debug.Assert(false, Ex.ToString()); RV = false; OnIdle(); } return RV; } /// <summary> /// Shells the command to disconnect from the VPN connection /// </summary> /// <returns>True if successfully disconnected</returns> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> private bool DisconnectFromVPN() { bool RV = false; try { OnDisconnecting(); System.Diagnostics.Process.Start(VPNPROCESS, " -h " + _VPNConnectionName); System.Windows.Forms.Application.DoEvents(); System.Threading.Thread.Sleep(8000); System.Windows.Forms.Application.DoEvents(); RV = true; OnIdle(); } catch (Exception Ex) { Debug.Assert(false, Ex.ToString()); RV = false; OnIdle(); } return RV; } /// <summary> /// Handles the grunt work. /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> private void Manage() { try { if (!_isManaging) { _isManaging = true; if (!_isChecking) { if (!TestConnection()) { ConnectToVPN(); if (!TestConnection()) { DisconnectFromVPN(); ConnectToVPN(); if (!TestConnection()) { DisconnectFromVPN(); ConnectToVPN(); } } } } _isManaging = false; } } catch (Exception) { _isManaging = false; } } #endregion #region --Public Methods-- /// <summary> /// Overloaded end point to begin monitoring VPN status /// </summary> /// <param name="VPNName">Name of VPN connection as seen in network connections (not case sensitive)</param> /// <param name="IPtoPing">IP to ping to validate connectivity</param> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public void StartManaging(string VPNName, string IPtoPing) { _VPNConnectionName = VPNName; _IPToPing = IPtoPing; StartManaging(); } /// <summary> /// End point to begin monitoring VPN status /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public void StartManaging() { if (!string.IsNullOrEmpty(_VPNConnectionName) & !string.IsNullOrEmpty(_IPToPing)) { MonitorTimer = new System.Timers.Timer(15000); MonitorTimer.Enabled = true; MonitorTimer.Elapsed += new System.Timers.ElapsedEventHandler(MonitorTimer_Elapsed); System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged += new System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged); Microsoft.Win32.SystemEvents.PowerModeChanged += new Microsoft.Win32.PowerModeChangedEventHandler(SystemEvents_PowerModeChanged); Manage(); } } #endregion #region --Constructors-- /// <summary> /// Overloaded constructor /// </summary> /// <param name="VPNName">Name of VPN connection as seen in network connections (not case sensitive)</param> /// <param name="IPtoPing">IP to ping to validate connectivity</param> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public VPN(string VPNName, string IPtoPing) { StartManaging(VPNName, IPtoPing); } /// <summary> /// Default empty constructor /// </summary> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> public VPN() { } #endregion #region --Event Handlers-- /// <summary> /// Handles the event that is raised when the computer goes into, or comes out of, standby. Very useful for laptops /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e) { if (e.Mode == Microsoft.Win32.PowerModes.Resume) { MonitorTimer.Stop(); System.Threading.Thread.Sleep(15000); MonitorTimer.Start(); } if (e.Mode == Microsoft.Win32.PowerModes.Suspend) { MonitorTimer.Stop(); } } /// <summary> /// Handles the event that is raised when the network status changes /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> void NetworkChange_NetworkAvailabilityChanged(object sender, System.Net.NetworkInformation.NetworkAvailabilityEventArgs e) { if (e.IsAvailable) { if (!MonitorTimer.Enabled) { MonitorTimer.Start(); } } else { MonitorTimer.Stop(); } } /// <summary> /// Handles the event the timer raises when it elapses /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <history> /// [Tim Hibbard] 01/24/2007 Created /// </history> void MonitorTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { Manage(); } #endregion } }

Print | posted on Monday, January 22, 2007 9:14 AM |

Feedback

Gravatar

# re: C# code to maintain VPN connection programatically

By using your code we are trying to connect VPN without populating the VPN dialog box we are passing the username ,password(secure string) as shown below.
our purpose is to establish the VPN connection through coding .

Please help us in finding a solution.




private bool ConnectToVPN()
{
bool RV = false;
try
{
OnConnecting();


string TEXTDATA = "123456";
System.Security.SecureString secretString = new System.Security.SecureString();
foreach (char c in TEXTDATA)
secretString.AppendChar(c);


ProcessStartInfo myProcess = new ProcessStartInfo(VPNPROCESS);
myProcess.Arguments = VPNConnectionName;
myProcess.UserName = "aaaaaa";

myProcess.Password = secretString;
myProcess.Domain = "";

myProcess.UseShellExecute = false;
Process.Start(myProcess);


System.Windows.Forms.Application.DoEvents();
System.Threading.Thread.Sleep(5000);
System.Windows.Forms.Application.DoEvents();
RV = true;
OnIdle();

}
catch (Exception Ex)
{
Debug.Assert(false, Ex.ToString());
RV = false;
OnIdle();
}
return RV;
}
7/4/2007 6:25 AM | samyvel
Gravatar

# re: C# code to maintain VPN connection programatically

My VPN connection takes PIN for connection. How can I pass it?
8/17/2007 7:33 AM | Prashant
Gravatar

# re: C# code to maintain VPN connection programatically

how do i save the code? as a .bat file??

I'm trying to use your code to make my connection manager dial automatic at startup
9/17/2007 11:01 PM | Jonathan
Gravatar

# re: C# code to maintain VPN connection programatically

How to use this code?
1/7/2009 11:52 AM | Michael
Gravatar

# re: C# code to maintain VPN connection programatically

Excellent class! 2 questions only: 1. Pinging doesn´t generate overhead or excesive traffic in VPN? 2. Pinging can reduce disconnection problem beacuse it is "sensing" or "keeping-alive" VPN connection?
1/15/2009 12:39 AM | JOrozco
Gravatar

# re: C# code to maintain VPN connection programatically

Why you use rasphone.exe do not rasdial.exe?
3/19/2009 3:06 AM | MVit
Gravatar

# re: C# code to maintain VPN connection programatically

Might want to check out the DotRas project on CodePlex. I've spent the last year or so creating a .NET API to control the Windows dialer without using the executables.

http://www.codeplex.com/DotRas

It has a lot of functionality with controlling the dialer, along with many other components such as the RasConnectionWatcher which receives notifications from Windows if connections are made or lost.
3/25/2009 10:39 AM | Jeff Winn
Gravatar

# re: C# code to maintain VPN connection programatically

i need a delegates to pinging with my id to remote id through programming.if u have any code for that.
8/1/2009 12:08 PM | harihar
Gravatar

# re: C# code to maintain VPN connection programatically

i need a delegates to pinging with my ip address to remote ip address through programming.if u have any code for that.
8/1/2009 12:09 PM | harihar
Gravatar

# VPN Works now i want to Connect to SQl

i have used the VPN code that you provided here and its working fine and i added an ado.net code to connect to an SQl Instance to the VPN Network. But i cant see to get in. i can ping the server but i cant access the SQL instance

THanks
4/14/2010 9:10 AM | Vuyiswa Maseko
Gravatar

# re: C# code to maintain VPN connection programatically

It is good... I have one question.. How we can check the VPN connection status.
4/26/2010 8:30 AM | Raghu
Gravatar

# re: C# code to maintain VPN connection programatically

this code helps me a lot.
Excellent
8/31/2010 1:55 AM | bhavana
Gravatar

# re: C# code to maintain VPN connection programatically

thanks alot..
very very thanks :)
2/8/2011 6:16 AM | Tamer
Gravatar

# re: C# code to maintain VPN connection programatically

hi...

i need to implement the vpn connection to my c++ application..

how can i do the vpn connection in c++.

please give me the solution as soon as possible......

thanks in advance...

thanks a lot...:)
5/10/2011 6:14 AM | praveena
Gravatar

# re: C# code to maintain VPN connection programatically

I''m saving this down and test it later.
6/3/2011 1:24 PM | bealls coupons
Gravatar

# re: C# code to maintain VPN connection programatically

Hi, thanks for sharing.
but we can also implement it by DotRAS SDK.
here is the implementation using mentioned SDK
http://www.dotnetobject.com/showthread.php?tid=1778
8/22/2011 1:24 PM | Nisar
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 

Powered by: