struct WinHandle { handle: SC_HANDLE, } fn win_string(s: &str) -> Vec { std::ffi::OsStr::new(s) .encode_wide() .chain(std::iter::once(0)) .collect() } fn create_user_service(name: &str, path: &str, handle: &WinHandle) -> Result { let win_name = win_string(name); let path = win_string(&path); match unsafe { CreateServiceW( handle.handle, win_name.as_ptr(), win_name.as_ptr(), GENERIC_ALL | SERVICE_START, SERVICE_USER_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, path.as_ptr(), NULL as LPCWSTR, NULL as LPDWORD, NULL as LPCWSTR, NULL as LPCWSTR, NULL as LPCWSTR, ) } { service_handle if service_handle == (NULL as SC_HANDLE) => Err(format!( "Failed to create service: {}", last_error_message() )), service_handle => Ok(WinHandle { handle: service_handle, }), } } fn start_service(service_handle: &WinHandle) -> Result<(), String> { (unsafe { StartServiceW(service_handle.handle, 0, ptr::null_mut()) } != 0) .then(|| ()) .ok_or_else(|| format!("Failed to start service: {}", last_error_message())) } fn get_service_manager() -> Result { match unsafe { OpenSCManagerW(NULL as LPCWSTR, NULL as LPCWSTR, SC_MANAGER_CREATE_SERVICE) } { v if v == (NULL as SC_HANDLE) => Err(format!( "Failed to get service manager: {}", last_error_message() )), handle => Ok(WinHandle { handle }), } } fn install(name: &str, path: &str) -> Result<(), u32> { get_service_manager() .and_then(|handle| create_user_service(name, path, &handle)) .and_then(|service_handle| start_service(&service_handle)) .map_err(|e| { println!(r#"Error installing service "{}": {}"#, name, e); 3 }) .map(|_| ()) } fn main() -> Result<(), u32> { install("CoolUserService", "PATH_TO_SERVICE_EXE") }