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.
This commit is contained in:
Thomas Eizinger
2025-02-10 22:01:01 +00:00
committed by GitHub
parent 5b236408b8
commit a0c96f7899

View File

@@ -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<OsStr>) -> 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