feat: add fallback tunnel status check and improve Windows service command calls
Add fallback to tunnel_status when metrics query fails in current_metrics function, returning zero bytes with actual tunnel state. Update waitForTunnelStatus in frontend to use tunnel_status instead of tunnel_metrics for status polling and refresh metrics separately on success. Change CloseRequested window event handler to call app_handle().exit(0) instead of no-op. Replace "sc" with "sc.exe" in all Windows service command
This commit is contained in:
@@ -403,11 +403,21 @@ fn current_metrics(app: &AppHandle) -> Result<TunnelMetrics, String> {
|
|||||||
let session = session.as_ref().ok_or_else(|| "No active session is available".to_string())?;
|
let session = session.as_ref().ok_or_else(|| "No active session is available".to_string())?;
|
||||||
session.profile_path.clone()
|
session.profile_path.clone()
|
||||||
};
|
};
|
||||||
tunnel_manager::metrics(app, std::path::Path::new(&profile_path)).map(|metrics| TunnelMetrics {
|
match tunnel_manager::metrics(app, std::path::Path::new(&profile_path)) {
|
||||||
|
Ok(metrics) => Ok(TunnelMetrics {
|
||||||
active: metrics.active,
|
active: metrics.active,
|
||||||
rx_bytes: metrics.rx_bytes,
|
rx_bytes: metrics.rx_bytes,
|
||||||
tx_bytes: metrics.tx_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<SessionState, String> {
|
async fn sync_current_session(app: &AppHandle) -> Result<SessionState, String> {
|
||||||
@@ -658,7 +668,9 @@ pub fn run() {
|
|||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.on_window_event(|window, event| match event {
|
.on_window_event(|window, event| match event {
|
||||||
WindowEvent::CloseRequested { .. } => {}
|
WindowEvent::CloseRequested { .. } => {
|
||||||
|
window.app_handle().exit(0);
|
||||||
|
}
|
||||||
WindowEvent::Resized(_) => {
|
WindowEvent::Resized(_) => {
|
||||||
if window.is_minimized().unwrap_or(false) {
|
if window.is_minimized().unwrap_or(false) {
|
||||||
hide_main_window(window);
|
hide_main_window(window);
|
||||||
|
|||||||
@@ -87,8 +87,15 @@ export function App() {
|
|||||||
const value = await invoke<TunnelMetrics>("tunnel_metrics");
|
const value = await invoke<TunnelMetrics>("tunnel_metrics");
|
||||||
setMetrics(value);
|
setMetrics(value);
|
||||||
setConnected(value.active);
|
setConnected(value.active);
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
const active = await invoke<boolean>("tunnel_status");
|
||||||
|
setConnected(active);
|
||||||
|
setMetrics((current) => ({ ...current, active }));
|
||||||
} catch {
|
} catch {
|
||||||
setMetrics({ active: false, rxBytes: 0, txBytes: 0 });
|
setMetrics({ active: false, rxBytes: 0, txBytes: 0 });
|
||||||
|
setConnected(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,15 +129,16 @@ export function App() {
|
|||||||
async function waitForTunnelStatus(expected: boolean) {
|
async function waitForTunnelStatus(expected: boolean) {
|
||||||
for (let attempt = 0; attempt < 8; attempt += 1) {
|
for (let attempt = 0; attempt < 8; attempt += 1) {
|
||||||
try {
|
try {
|
||||||
const value = await invoke<TunnelMetrics>("tunnel_metrics");
|
const active = await invoke<boolean>("tunnel_status");
|
||||||
setMetrics(value);
|
setConnected(active);
|
||||||
setConnected(value.active);
|
if (active === expected) {
|
||||||
if (value.active === expected) {
|
await refreshTunnelMetrics();
|
||||||
return value.active;
|
return active;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
if (!expected) {
|
if (!expected) {
|
||||||
setMetrics({ active: false, rxBytes: 0, txBytes: 0 });
|
setMetrics({ active: false, rxBytes: 0, txBytes: 0 });
|
||||||
|
setConnected(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,11 +146,11 @@ export function App() {
|
|||||||
await new Promise((resolve) => window.setTimeout(resolve, 500));
|
await new Promise((resolve) => window.setTimeout(resolve, 500));
|
||||||
}
|
}
|
||||||
|
|
||||||
return invoke<TunnelMetrics>("tunnel_metrics")
|
return invoke<boolean>("tunnel_status")
|
||||||
.then((value) => {
|
.then(async (active) => {
|
||||||
setMetrics(value);
|
setConnected(active);
|
||||||
setConnected(value.active);
|
await refreshTunnelMetrics();
|
||||||
return value.active;
|
return active;
|
||||||
})
|
})
|
||||||
.catch(() => false);
|
.catch(() => false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -479,7 +479,7 @@ fn connect_to_service() -> Result<TcpStream, String> {
|
|||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
fn start_windows_service() -> Result<(), String> {
|
fn start_windows_service() -> Result<(), String> {
|
||||||
let status = Command::new("sc")
|
let status = Command::new("sc.exe")
|
||||||
.arg("start")
|
.arg("start")
|
||||||
.arg(SERVICE_NAME)
|
.arg(SERVICE_NAME)
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
@@ -610,7 +610,7 @@ fn tunnel_service_is_active(profile: &Path) -> Result<bool, String> {
|
|||||||
{
|
{
|
||||||
let tunnel_name = tunnel_name(profile)?;
|
let tunnel_name = tunnel_name(profile)?;
|
||||||
let service_name = format!("WireGuardTunnel${}", tunnel_name);
|
let service_name = format!("WireGuardTunnel${}", tunnel_name);
|
||||||
let output = Command::new("sc")
|
let output = Command::new("sc.exe")
|
||||||
.arg("query")
|
.arg("query")
|
||||||
.arg(&service_name)
|
.arg(&service_name)
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
@@ -659,7 +659,7 @@ fn describe_windows_tunnel_state(profile: &Path) -> String {
|
|||||||
Err(err) => return err,
|
Err(err) => return err,
|
||||||
};
|
};
|
||||||
let service_name = format!("WireGuardTunnel${}", tunnel_name);
|
let service_name = format!("WireGuardTunnel${}", tunnel_name);
|
||||||
let output = Command::new("sc")
|
let output = Command::new("sc.exe")
|
||||||
.arg("query")
|
.arg("query")
|
||||||
.arg(&service_name)
|
.arg(&service_name)
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
|
|||||||
Reference in New Issue
Block a user