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 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}