title: How do I programmatically disconnect an OpenVPN connection?
body: <p>I am creating a WinForms application to start and stop an OpenVPN connection on Windows. I am trying to achieve the same functionality as OpenVPN GUI for Windows (<a href="http://openvpn.se/" rel="nofollow noreferrer">http://openvpn.se/</a>) provides but using my own .NET based UI.</p>
  
  <p>I am starting the connection using the following approach:</p>
  
  <pre><code>Process openVpnProcess = new Process();
  openVpnProcess.StartInfo.CreateNoWindow = true;
  openVpnProcess.EnableRaisingEvents = true;
  openVpnProcess.StartInfo.Arguments = "--config client.ovpn";
  openVpnProcess.StartInfo.FileName = "openvpn.exe";
  openVpnProcess.StartInfo.WorkingDirectory = @"C:\Program Files\OpenVPN\config";
  openVpnProcess.Start();
  </code></pre>
  
  <p>This invokes openvpn.exe and the connection is established successfully. </p>
  
  <p>I am however unable to determine a way to terminate the connection once it is established. I have tried using Process.Kill() </p>
  
  <pre><code>foreach (var p in Process.GetProcessesByName("openvpn"))
  {
      p.Kill();
  }
  </code></pre>
  
  <p>This kills the process, but does not restore the initial routing state. Effectively, I cannot access the network until I manually disable/enable my LAN card.</p>
  
  <p>Output of 'openvpn --show-net' before the VPN connection is established:</p>
  
  <pre><code>SYSTEM ROUTING TABLE
  0.0.0.0 0.0.0.0 10.31.0.254 p=0 i=1376258 t=4 pr=3 a=21 h=0 m=1/-1/-1/-1/-1
  10.31.0.0 255.255.240.0 10.31.10.235 p=0 i=1376258 t=3 pr=2 a=26 h=0 m=20/-1/-1/-1/-1
  10.31.10.235 255.255.255.255 127.0.0.1 p=0 i=1 t=3 pr=2 a=26 h=0 m=20/-1/-1/-1/-1
  10.255.255.255 255.255.255.255 10.31.10.235 p=0 i=1376258 t=3 pr=2 a=26 h=0 m=20/-1/-1/-1/-1
  127.0.0.0 255.0.0.0 127.0.0.1 p=0 i=1 t=3 pr=2 a=116753 h=0 m=1/-1/-1/-1/-1
  224.0.0.0 240.0.0.0 10.31.10.235 p=0 i=1376258 t=3 pr=2 a=26 h=0 m=20/-1/-1/-1/-1
  255.255.255.255 255.255.255.255 10.31.10.235 p=0 i=1376258 t=3 pr=2 a=26 h=0 m=1/-1/-1/-1/-1
  255.255.255.255 255.255.255.255 10.31.10.235 p=0 i=1441796 t=3 pr=2 a=4 h=0 m=1/-1/-1/-1/-1
  SYSTEM ADAPTER LIST
  TAP-Win32 Adapter V8
    Index = 1441796
    GUID = {013AB57F-DFE6-4FD9-B25E-9589E77DA4EB}
    IP = 0.0.0.0/0.0.0.0
    MAC = 00:ff:01:3a:b5:7f
    GATEWAY =
    DHCP SERV = 172.16.0.0
    DHCP LEASE OBTAINED = Tue Jul 07 16:35:20 2009
    DHCP LEASE EXPIRES  = Wed Jul 07 16:35:20 2010
  D-Link DFE-538TX 10/100 Adapter
    Index = 1376258
    GUID = {FB6051A1-E970-4F46-BB85-F442A194BA3D}
    IP = 10.31.10.235/255.255.240.0
    MAC = 00:08:a1:65:70:93
    GATEWAY = 10.31.0.254/0.0.0.0
  </code></pre>
  
  <p>'openvpn --show-net' after VPN connection is closed using Process.Kill():</p>
  
  <pre><code>SYSTEM ROUTING TABLE
  10.31.0.0 255.255.240.0 10.31.10.235 p=0 i=1376258 t=3 pr=2 a=106 h=0 m=20/-1/-1/-1/-1
  10.31.10.235 255.255.255.255 127.0.0.1 p=0 i=1 t=3 pr=2 a=106 h=0 m=20/-1/-1/-1/-1
  10.255.255.255 255.255.255.255 10.31.10.235 p=0 i=1376258 t=3 pr=2 a=106 h=0 m=20/-1/-1/-1/-1
  127.0.0.0 255.0.0.0 127.0.0.1 p=0 i=1 t=3 pr=2 a=116833 h=0 m=1/-1/-1/-1/-1
  208.94.64.10 255.255.255.255 10.31.0.254 p=0 i=1376258 t=4 pr=3 a=21 h=0 m=1/-1/-1/-1/-1
  224.0.0.0 240.0.0.0 10.31.10.235 p=0 i=1376258 t=3 pr=2 a=106 h=0 m=20/-1/-1/-1/-1
  255.255.255.255 255.255.255.255 10.31.10.235 p=0 i=1376258 t=3 pr=2 a=106 h=0 m=1/-1/-1/-1/-1
  255.255.255.255 255.255.255.255 10.31.10.235 p=0 i=1441796 t=3 pr=2 a=84 h=0 m=1/-1/-1/-1/-1
  SYSTEM ADAPTER LIST
  TAP-Win32 Adapter V8
    Index = 1441796
    GUID = {013AB57F-DFE6-4FD9-B25E-9589E77DA4EB}
    IP = 0.0.0.0/0.0.0.0
    MAC = 00:ff:01:3a:b5:7f
    GATEWAY =
    DHCP SERV = 172.16.0.0
    DHCP LEASE OBTAINED = Tue Jul 07 17:02:30 2009
    DHCP LEASE EXPIRES  = Wed Jul 07 17:02:30 2010
  D-Link DFE-538TX 10/100 Adapter
    Index = 1376258
    GUID = {FB6051A1-E970-4F46-BB85-F442A194BA3D}
    IP = 10.31.10.235/255.255.240.0
    MAC = 00:08:a1:65:70:93
    GATEWAY =
  </code></pre>
  
  <p>I also tried sending the process <code>WM_CLOSE / WM_QUIT / WM_ENDMESSAGE</code> messages but these did not produce any result.</p>
  
  <pre><code>const int WM_CLOSE = 0x10;
  const int WM_QUIT = 0x12;
  const int WM_ENDSESSION = 0x0016;
  
  [DllImport("user32.dll")]
  public static extern int SendMessage(int hwnd, int msg, int wparam, int lparam);
  
  foreach (var p in Process.GetProcessesByName("openvpn"))
  {
      SendMessage(p.Handle.ToInt32(), WM_CLOSE, 0, 0);
      SendMessage(p.Handle.ToInt32(), WM_QUIT, 0, 0);
      SendMessage(p.Handle.ToInt32(), WM_ENDSESSION, 0, 0);
  }
  </code></pre>
  
  <hr>
  
  <p><strong>Further info on the appropriate solution:</strong> See instructions in section titled <em>Using the management interface</em> in <a href="http://openvpn.net/index.php/open-source/documentation/howto.html#control" rel="nofollow noreferrer">Controlling a running OpenVPN process</a>.</p>
  
  <p>More info on using <a href="http://geekswithblogs.net/bigpapa/archive/2007/10/08/C-2.0-and-Telnet---Not-As-Painful-As-It.aspx" rel="nofollow noreferrer">Telnet from C#</a>.</p>