Вопрос

Я создаю приложение WinForms для запуска и остановки соединения OpenVPN в Windows.Я пытаюсь добиться той же функциональности, что и графический интерфейс OpenVPN для Windows (http://openvpn.se/) предоставляет, но использует мой собственный пользовательский интерфейс на основе .NET.

Я начинаю соединение, используя следующий подход:

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();

Это вызывает openvpn.exe, и соединение устанавливается успешно.

Однако я не могу определить способ разорвать соединение после его установления.Я пробовал использовать Process.Kill()

foreach (var p in Process.GetProcessesByName("openvpn"))
{
    p.Kill();
}

Это убивает процесс, но не восстанавливает исходное состояние маршрутизации.По сути, я не могу получить доступ к сети, пока вручную не отключу/включу свою сетевую карту.

Вывод команды openvpn --show-net перед установкой VPN-соединения:

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

'openvpn --show-net' после закрытия VPN-соединения с помощью Process.Kill():

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 =

Я также попробовал отправить процесс WM_CLOSE / WM_QUIT / WM_ENDMESSAGE сообщения, но они не дали никакого результата.

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);
}

Дополнительная информация о соответствующем решении: См. инструкции в разделе под названием Использование интерфейса управления в Управление запущенным процессом OpenVPN.

Дополнительная информация об использовании Telnet из C#.

Это было полезно?

Решение

Я не пробовал это в Windows, но вы можете использовать Интерфейс управления OpenVPN отправить SIGTERM сигнал с помощью signal команда.Разумеется, вам необходимо включить записи конфигурации интерфейса управления в файл конфигурации.

Более подробная информация в Страница руководства OpenVPN

Возможно, вы захотите посмотреть на путь OpenVPN-администратор делает что-то.Он работает под Windows и Linux и разработан с помощью Mono.

Другие советы

Вы отправляете сообщения дескриптору процесса, однако это окно сообщения, поэтому их необходимо отправлять на окно ручка.

РЕДАКТИРОВАТЬ
Поскольку вы уже освоили этот процесс, вы можете попробовать следующее:

foreach (var p in Process.GetProcessesByName("openvpn"))
{
    p.CloseMainWindow();
}

или

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hwnd, int msg, int wparam, int lparam);

foreach (var p in Process.GetProcessesByName("openvpn"))
{
    IntPtr hWnd = p.MainWindowHandle;
    // Send message to hWnd (mind SendMessage's changed signature)
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top