Here's how to use it:
//Get a VPN connector ready VPNConnector vpn = new VPNConnector("VPN_NAME", "USER_NAME", "USER_PASSWORD"); //Connect Tuple<bool, IList<string>> response = vpn.Connect(); if (response.Item1) { //Successfully connected Console.WriteLine("Connected!"); } else { //Failed to connect Console.WriteLine("Failed to connect :("); foreach (string s in response.Item2) { Console.WriteLine(s); } } //Disconnect vpn.Disconnect();
You can optionally check if the connection is already open by using vpn.IsOpen.
The code:
/// <summary> /// Gives access to Windows VPN connections /// </summary> public class VPNConnector { #region Properties #region VPNName /// <summary> /// The name of the VPN connection /// </summary> public string VPNName { get; set; } #endregion #region Username /// <summary> /// The username to use for the connection /// </summary> public string Username { get; set; } #endregion #region Password /// <summary> /// The password to use for the connection /// </summary> public string Password { get; set; } #endregion #region IsOpen /// <summary> /// Whether the connection is currently open or not /// </summary> public bool IsOpen { get { if (String.IsNullOrWhiteSpace(this.VPNName)) throw new ArgumentException("No VPN name (VPNName) has been set"); Process p = this.getNewProcess; p.Start(); bool bOpen = false; while (!p.StandardOutput.EndOfStream) { string sOutput = p.StandardOutput.ReadLine(); if (sOutput.ToLower() != "no connections") { if (sOutput == this.VPNName) { bOpen = true; break; } } else break; } p.WaitForExit(); return bOpen; } } #endregion #region parametersAreASet /// <summary> /// Determines if all the necessary parameters are set to make a VPN connection /// </summary> private bool parametersAreASet { get { return (!String.IsNullOrWhiteSpace(this.VPNName) && !String.IsNullOrWhiteSpace(this.Username) && !String.IsNullOrWhiteSpace(this.Password)); } } #endregion #region getNewProcess /// <summary> /// Get a new process ready to start a rasdial call /// </summary> private Process getNewProcess { get { return new Process { StartInfo = new ProcessStartInfo { FileName = "rasdial.exe", UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true } }; } } #endregion #endregion #region Cosntructor public VPNConnector() { } public VPNConnector(string name, string username, string password) { this.VPNName = name; this.Username = username; this.Password = password; if (!this.parametersAreASet) throw new ArgumentException("All arguments must have a value"); } #endregion #region Public Methods #region Instance #region Connect /// <summary> /// Make a connection to the VPN. Item1 of Tuple indicates success or failure. Item2 of Tuple is the output of the dial call /// </summary> public Tuple<bool, IList<string>> Connect() { if (!this.IsOpen) { if (!this.parametersAreASet) throw new ArgumentException("All arguments must have a value"); Process p = this.getNewProcess; p.StartInfo.Arguments = $"\"{this.VPNName}\" \"{this.Username}\" \"{ this.Password}\""; p.Start(); bool bSuccess = false; IList<string> outputs = new List<string>(); while (!p.StandardOutput.EndOfStream) { string sOutput = p.StandardOutput.ReadLine(); outputs.Add(sOutput); if (sOutput.ToLower().StartsWith("success")) bSuccess = true; } p.WaitForExit(); return new Tuple<bool, IList<string>>(bSuccess, outputs); } else return new Tuple<bool, IList<string>>(false, new List<string>() { "Connection already open" } ); } #endregion #region Disconnect /// <summary> /// Disconnect from the VPN. Item1 of Tuple indicates success or failure. Item2 of Tuple is the output of the dial call /// </summary> public Tuple<bool, IList<string>> Disconnect() { if (this.IsOpen) { Process p = this.getNewProcess; p.StartInfo.Arguments = $"\"{this.VPNName}\" /d"; p.Start(); bool bSuccess = false; IList<string> outputs = new List<string>(); while (!p.StandardOutput.EndOfStream) { string sOutput = p.StandardOutput.ReadLine(); outputs.Add(sOutput); if (sOutput.ToLower().Contains("success")) bSuccess = true; } p.WaitForExit(); return new Tuple<bool, IList<string>>(bSuccess, outputs); } else return new Tuple<bool, IList<string>>(false, new List<string>() { "Connection already closed" }); } #endregion #endregion #endregion }