manager/
manager.rs

1use std::{env, io, process};
2use std::{io::Write as _, time::Duration};
3
4use uni_service_manager::{ServiceCapabilities, ServiceSpec, UniServiceManager};
5
6const TIMEOUT: Duration = Duration::from_secs(5);
7
8fn run(
9    service_name: &str,
10    display_name: &str,
11    description: &str,
12) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
13    // Windows user services require a new logon before they can be started, so we will use a system service on Windows.
14    // NOTE: Windows services always require elevated privileges to install, so run this example as administrator.
15    let user = !UniServiceManager::capabilities()
16        .contains(ServiceCapabilities::USER_SERVICES_REQUIRE_NEW_LOGON);
17    let user_manager = UniServiceManager::new(service_name, "com.example.", user)?;
18
19    let mut bin_path = std::env::current_exe().unwrap();
20    bin_path.set_file_name(service_name);
21
22    if !bin_path.exists() {
23        return Err(format!(
24            "Executable not found: {}. Make sure to build the service examples first.",
25            bin_path.display()
26        )
27        .into());
28    }
29
30    let spec = ServiceSpec::new(bin_path)
31        .arg("service")?
32        .display_name(display_name)?
33        .description(description)?;
34
35    print!("Installing service '{service_name}'...",);
36    user_manager.install_and_wait(&spec, TIMEOUT)?;
37    println!("done");
38
39    print!("Starting service '{service_name}'...");
40    user_manager.start_and_wait(TIMEOUT)?;
41    println!("done");
42
43    io::stdout().flush()?;
44    println!("Press Enter to stop the service...");
45    let mut buffer = String::new();
46    io::stdin().read_line(&mut buffer)?;
47
48    print!("Stopping service '{service_name}'...");
49    user_manager.stop_and_wait(TIMEOUT)?;
50    println!("done");
51
52    print!("Uninstalling service '{service_name}'...");
53    user_manager.uninstall_and_wait(TIMEOUT)?;
54    println!("done");
55
56    Ok(())
57}
58
59fn main() {
60    if env::args().len() < 2 {
61        eprintln!("Usage: manager <service_name>");
62        process::exit(1);
63    }
64    let service_name = env::args().nth(1).unwrap();
65
66    let (display_name, description) = match service_name.as_str() {
67        "axum" => ("Axum Service", "Axum service"),
68        "hello_world" => ("Hello World", "Hello World service"),
69        _ => {
70            eprintln!("Unknown service: {}", service_name);
71            process::exit(1);
72        }
73    };
74
75    if let Err(e) = run(&service_name, display_name, description) {
76        eprintln!("Error: {}", e);
77        process::exit(1);
78    }
79}