uninstall_service/
uninstall_service.rs

1#[cfg(windows)]
2fn main() -> windows_service::Result<()> {
3    use std::{
4        thread::sleep,
5        time::{Duration, Instant},
6    };
7
8    use windows_service::{
9        service::{ServiceAccess, ServiceState},
10        service_manager::{ServiceManager, ServiceManagerAccess},
11    };
12    use windows_sys::Win32::Foundation::ERROR_SERVICE_DOES_NOT_EXIST;
13
14    let manager_access = ServiceManagerAccess::CONNECT;
15    let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)?;
16
17    let service_access = ServiceAccess::QUERY_STATUS | ServiceAccess::STOP | ServiceAccess::DELETE;
18    let service = service_manager.open_service("ping_service", service_access)?;
19
20    // The service will be marked for deletion as long as this function call succeeds.
21    // However, it will not be deleted from the database until it is stopped and all open handles to it are closed.
22    service.delete()?;
23    // Our handle to it is not closed yet. So we can still query it.
24    if service.query_status()?.current_state != ServiceState::Stopped {
25        // If the service cannot be stopped, it will be deleted when the system restarts.
26        service.stop()?;
27    }
28    // Explicitly close our open handle to the service. This is automatically called when `service` goes out of scope.
29    drop(service);
30
31    // Win32 API does not give us a way to wait for service deletion.
32    // To check if the service is deleted from the database, we have to poll it ourselves.
33    let start = Instant::now();
34    let timeout = Duration::from_secs(5);
35    while start.elapsed() < timeout {
36        if let Err(windows_service::Error::Winapi(e)) =
37            service_manager.open_service("ping_service", ServiceAccess::QUERY_STATUS)
38        {
39            if e.raw_os_error() == Some(ERROR_SERVICE_DOES_NOT_EXIST as i32) {
40                println!("ping_service is deleted.");
41                return Ok(());
42            }
43        }
44        sleep(Duration::from_secs(1));
45    }
46    println!("ping_service is marked for deletion.");
47
48    Ok(())
49}
50
51#[cfg(not(windows))]
52fn main() {
53    panic!("This program is only intended to run on Windows.");
54}