diff --git a/desktop-client/src-tauri/src/lib.rs b/desktop-client/src-tauri/src/lib.rs index a7e6fd2..08e26ad 100644 --- a/desktop-client/src-tauri/src/lib.rs +++ b/desktop-client/src-tauri/src/lib.rs @@ -403,11 +403,21 @@ fn current_metrics(app: &AppHandle) -> Result { let session = session.as_ref().ok_or_else(|| "No active session is available".to_string())?; session.profile_path.clone() }; - tunnel_manager::metrics(app, std::path::Path::new(&profile_path)).map(|metrics| TunnelMetrics { - active: metrics.active, - rx_bytes: metrics.rx_bytes, - tx_bytes: metrics.tx_bytes, - }) + match tunnel_manager::metrics(app, std::path::Path::new(&profile_path)) { + Ok(metrics) => Ok(TunnelMetrics { + active: metrics.active, + rx_bytes: metrics.rx_bytes, + tx_bytes: metrics.tx_bytes, + }), + Err(_) => { + let active = tunnel_manager::is_active(app, std::path::Path::new(&profile_path))?; + Ok(TunnelMetrics { + active, + rx_bytes: 0, + tx_bytes: 0, + }) + } + } } async fn sync_current_session(app: &AppHandle) -> Result { @@ -658,7 +668,9 @@ pub fn run() { Ok(()) }) .on_window_event(|window, event| match event { - WindowEvent::CloseRequested { .. } => {} + WindowEvent::CloseRequested { .. } => { + window.app_handle().exit(0); + } WindowEvent::Resized(_) => { if window.is_minimized().unwrap_or(false) { hide_main_window(window); diff --git a/desktop-client/src/App.tsx b/desktop-client/src/App.tsx index 5bb6e0c..bb649cc 100644 --- a/desktop-client/src/App.tsx +++ b/desktop-client/src/App.tsx @@ -88,7 +88,14 @@ export function App() { setMetrics(value); setConnected(value.active); } catch { - setMetrics({ active: false, rxBytes: 0, txBytes: 0 }); + try { + const active = await invoke("tunnel_status"); + setConnected(active); + setMetrics((current) => ({ ...current, active })); + } catch { + setMetrics({ active: false, rxBytes: 0, txBytes: 0 }); + setConnected(false); + } } } @@ -122,15 +129,16 @@ export function App() { async function waitForTunnelStatus(expected: boolean) { for (let attempt = 0; attempt < 8; attempt += 1) { try { - const value = await invoke("tunnel_metrics"); - setMetrics(value); - setConnected(value.active); - if (value.active === expected) { - return value.active; + const active = await invoke("tunnel_status"); + setConnected(active); + if (active === expected) { + await refreshTunnelMetrics(); + return active; } } catch { if (!expected) { setMetrics({ active: false, rxBytes: 0, txBytes: 0 }); + setConnected(false); return false; } } @@ -138,11 +146,11 @@ export function App() { await new Promise((resolve) => window.setTimeout(resolve, 500)); } - return invoke("tunnel_metrics") - .then((value) => { - setMetrics(value); - setConnected(value.active); - return value.active; + return invoke("tunnel_status") + .then(async (active) => { + setConnected(active); + await refreshTunnelMetrics(); + return active; }) .catch(() => false); } diff --git a/desktop-client/tunnel-helper/src/main.rs b/desktop-client/tunnel-helper/src/main.rs index d180f0a..87ce51a 100644 --- a/desktop-client/tunnel-helper/src/main.rs +++ b/desktop-client/tunnel-helper/src/main.rs @@ -479,7 +479,7 @@ fn connect_to_service() -> Result { #[cfg(target_os = "windows")] fn start_windows_service() -> Result<(), String> { - let status = Command::new("sc") + let status = Command::new("sc.exe") .arg("start") .arg(SERVICE_NAME) .creation_flags(CREATE_NO_WINDOW) @@ -610,7 +610,7 @@ fn tunnel_service_is_active(profile: &Path) -> Result { { let tunnel_name = tunnel_name(profile)?; let service_name = format!("WireGuardTunnel${}", tunnel_name); - let output = Command::new("sc") + let output = Command::new("sc.exe") .arg("query") .arg(&service_name) .creation_flags(CREATE_NO_WINDOW) @@ -659,7 +659,7 @@ fn describe_windows_tunnel_state(profile: &Path) -> String { Err(err) => return err, }; let service_name = format!("WireGuardTunnel${}", tunnel_name); - let output = Command::new("sc") + let output = Command::new("sc.exe") .arg("query") .arg(&service_name) .creation_flags(CREATE_NO_WINDOW)