using System; using System.Diagnostics; using System.IO; using System.Net.NetworkInformation; using System.Windows.Forms; namespace CramLinkClientGUI { public partial class MainForm : Form { private Process vpnProcess; private System.Windows.Forms.Timer pingTimer = new System.Windows.Forms.Timer(); public MainForm() { InitializeComponent(); statusLabel.Text = "Disconnected"; siteComboBox.Items.AddRange(new[] { "CramLink 1 - HQ", "CramLink 2 - N/A" }); siteComboBox.SelectedIndex = 0; pingTimer.Interval = 5000; pingTimer.Tick += PingTargets; } private void connectButton_Click(object sender, EventArgs e) { if (vpnProcess != null && !vpnProcess.HasExited) { vpnProcess.Kill(); vpnProcess.Dispose(); vpnProcess = null; statusLabel.Text = "Disconnected"; connectButton.Text = "Connect"; logBox.AppendText("VPN disconnected.\r\n"); pingTimer.Stop(); return; } string configPath = "C:\\CramLinkVPN\\client.ovpn"; string openvpnPath = "C:\\CramLinkVPN\\openvpn.exe"; if (!File.Exists(configPath) || !File.Exists(openvpnPath)) { MessageBox.Show("OpenVPN executable or config not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } vpnProcess = new Process(); vpnProcess.StartInfo.FileName = openvpnPath; vpnProcess.StartInfo.Arguments = "--config \"" + configPath + "\""; vpnProcess.StartInfo.RedirectStandardOutput = true; vpnProcess.StartInfo.RedirectStandardError = true; vpnProcess.StartInfo.UseShellExecute = false; vpnProcess.StartInfo.CreateNoWindow = true; vpnProcess.OutputDataReceived += (s, args) => HandleVPNOutput(args.Data); vpnProcess.ErrorDataReceived += (s, args) => HandleVPNOutput(args.Data); vpnProcess.Start(); vpnProcess.BeginOutputReadLine(); vpnProcess.BeginErrorReadLine(); connectButton.Text = "Disconnect"; statusLabel.Text = "Connecting..."; logBox.AppendText("Connecting to VPN...\r\n"); } private void HandleVPNOutput(string data) { if (data == null) return; Invoke(new Action(() => { logBox.AppendText(data + "\r\n"); if (data.Contains("Initialization Sequence Completed")) { statusLabel.Text = "Connected"; pingTimer.Start(); } })); } private void PingTargets(object sender, EventArgs e) { bool piOnline = PingHost("192.168.0.53"); bool plcOnline = PingHost("192.168.0.98"); piStatus.ForeColor = piOnline ? System.Drawing.Color.Green : System.Drawing.Color.Red; plcStatus.ForeColor = plcOnline ? System.Drawing.Color.Green : System.Drawing.Color.Red; } private bool PingHost(string host) { try { using Ping ping = new Ping(); PingReply reply = ping.Send(host, 1000); return reply.Status == IPStatus.Success; } catch { return false; } } private void plcStatus_Click(object sender, EventArgs e) { } } }