#![cfg(windows)]
windows_service::define_windows_service!(ffi_service_main, my_service_main);
pub fn start_service() -> Result<(), windows_service::Error> {
windows_service::service_dispatcher::start("dns-over-https", ffi_service_main)?;
Ok(())
}
fn my_service_main(arguments: Vec<std::ffi::OsString>) {
if let Err(_e) = run_service(arguments) {
}
}
fn run_service(_arguments: Vec<std::ffi::OsString>) -> Result<(), crate::BoxError> {
use windows_service::service::ServiceControl;
use windows_service::service_control_handler::{self, ServiceControlHandlerResult};
let event_handler = move |control_event| -> ServiceControlHandlerResult {
match control_event {
ServiceControl::Stop => {
unsafe { crate::dns_over_https_stop() };
ServiceControlHandlerResult::NoError
}
ServiceControl::Interrogate => ServiceControlHandlerResult::NoError,
_ => ServiceControlHandlerResult::NotImplemented,
}
};
let status_handle = service_control_handler::register("dns-over-https", event_handler)?;
let mut next_status = windows_service::service::ServiceStatus {
service_type: windows_service::service::ServiceType::OWN_PROCESS,
current_state: windows_service::service::ServiceState::Running,
controls_accepted: windows_service::service::ServiceControlAccept::STOP,
exit_code: windows_service::service::ServiceExitCode::Win32(0),
checkpoint: 0,
wait_hint: std::time::Duration::default(),
process_id: None,
};
status_handle.set_service_status(next_status.clone())?;
let args = crate::Args::parse();
let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build()?;
rt.block_on(async {
crate::main_loop(&args).await?;
Ok::<(), crate::Error>(())
})?;
next_status.current_state = windows_service::service::ServiceState::Stopped;
status_handle.set_service_status(next_status)?;
Ok(())
}