From a0c96f7899c00dc20cb9400db774ff04617b085a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 10 Feb 2025 22:01:01 +0000 Subject: [PATCH] refactor(windows): don't fail install on missing IPC service (#8072) In order to test changes to the IPC service on Windows more easily, the IPC service binary offers an `install` command that installs a new "Debug" IPC service. Prior to that, the previous is uninstalled. This doesn't work if one doesn't have a previous "Debug" IPC service so the `install` command only works for devs that have at least run it once with that part of the function commented out. To improve this Dev UX, we don't abort if we can't uninstall the previous one. --- .../src/ipc_service/windows.rs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/rust/headless-client/src/ipc_service/windows.rs b/rust/headless-client/src/ipc_service/windows.rs index d9c6ca98e..e0dbaf34d 100644 --- a/rust/headless-client/src/ipc_service/windows.rs +++ b/rust/headless-client/src/ipc_service/windows.rs @@ -4,7 +4,7 @@ use firezone_bin_shared::platform::DnsControlMethod; use firezone_telemetry::Telemetry; use futures::channel::mpsc; use std::{ - ffi::{c_void, OsString}, + ffi::{c_void, OsStr, OsString}, mem::size_of, time::Duration, }; @@ -151,18 +151,18 @@ pub(crate) fn install_ipc_service() -> Result<()> { let manager_access = ServiceManagerAccess::CONNECT | ServiceManagerAccess::CREATE_SERVICE; let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)?; - let name = OsString::from("FirezoneClientIpcServiceDebug"); + let name = "FirezoneClientIpcServiceDebug"; // Un-install existing one first if needed + if let Err(e) = uninstall_ipc_service(&service_manager, name) + .with_context(|| format!("Failed to uninstall `{name}`")) { - let service_access = ServiceAccess::DELETE; - let service = service_manager.open_service(&name, service_access)?; - service.delete()?; + tracing::debug!("{e:#}"); } let executable_path = std::env::current_exe()?; let service_info = ServiceInfo { - name, + name: OsString::from(name), display_name: OsString::from("Firezone Client IPC (Debug)"), service_type: ServiceType::OWN_PROCESS, start_type: ServiceStartType::AutoStart, @@ -178,6 +178,14 @@ pub(crate) fn install_ipc_service() -> Result<()> { Ok(()) } +fn uninstall_ipc_service(service_manager: &ServiceManager, name: impl AsRef) -> Result<()> { + let service_access = ServiceAccess::DELETE; + let service = service_manager.open_service(name, service_access)?; + service.delete()?; + + Ok(()) +} + /// Cross-platform entry point for systemd / Windows services /// /// Linux uses the CLI args from here, Windows does not