mirror of
https://github.com/Xevion/smart-rgb.git
synced 2025-12-06 01:16:24 -06:00
Cleanup, add logon/lockoff listeners
This commit is contained in:
3
STORY.md
3
STORY.md
@@ -30,3 +30,6 @@ Resources:
|
|||||||
So initial studies were pretty confusing as most of the solutions for detecting changes in lock screen or sleep mode used `Wndproc`, which is a callback installed when creating a Window; a solution that I really wasn't interested in.
|
So initial studies were pretty confusing as most of the solutions for detecting changes in lock screen or sleep mode used `Wndproc`, which is a callback installed when creating a Window; a solution that I really wasn't interested in.
|
||||||
|
|
||||||
On top of being complex as hell, it required hiding the window manually using special `SW_HIDE` magic, and it sounded wrong. Also, I don't think services should have windows at all.
|
On top of being complex as hell, it required hiding the window manually using special `SW_HIDE` magic, and it sounded wrong. Also, I don't think services should have windows at all.
|
||||||
|
|
||||||
|
- [Detect if desktop is locked](https://stackoverflow.com/questions/768314/detect-if-desktop-is-locked)
|
||||||
|
- [How to detect wake up from sleep mode in windows service?](https://stackoverflow.com/questions/47942716/how-to-detect-wake-up-from-sleep-mode-in-windows-service)
|
||||||
88
src/main.rs
88
src/main.rs
@@ -1,9 +1,11 @@
|
|||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
|
||||||
|
use log::{info, debug};
|
||||||
|
use log4rs::Handle;
|
||||||
use windows_service::{
|
use windows_service::{
|
||||||
service::{ServiceAccess, ServiceErrorControl, ServiceInfo, ServiceStartType, ServiceType},
|
service::{ServiceAccess, ServiceErrorControl, ServiceInfo, ServiceStartType, ServiceType},
|
||||||
service_manager::{ServiceManager, ServiceManagerAccess},
|
|
||||||
service_control_handler::{self, ServiceControlHandlerResult},
|
service_control_handler::{self, ServiceControlHandlerResult},
|
||||||
|
service_manager::{ServiceManager, ServiceManagerAccess},
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -35,7 +37,7 @@ pub(crate) async fn rule_applier(
|
|||||||
// output = monitor_new_processes(&rule_set, &wmi_con) => output,
|
// output = monitor_new_processes(&rule_set, &wmi_con) => output,
|
||||||
// Or wait for shutdown signal
|
// Or wait for shutdown signal
|
||||||
_ = shutdown_recv.recv() => {
|
_ = shutdown_recv.recv() => {
|
||||||
println!("Shutting down process monitor");
|
info!("Shutting down process monitor");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,15 +45,36 @@ pub(crate) async fn rule_applier(
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn service_main(_: Vec<OsString>) {
|
fn service_main(_: Vec<OsString>) {
|
||||||
use windows_service::service::{ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus};
|
use windows_service::service::{
|
||||||
|
ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus,
|
||||||
|
SessionChangeReason,
|
||||||
|
};
|
||||||
|
|
||||||
let rt = Runtime::new().unwrap();
|
let rt = Runtime::new().unwrap();
|
||||||
let (shutdown_send, mut shutdown_recv) = mpsc::unbounded_channel();
|
let (shutdown_send, mut shutdown_recv) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
let event_handler = move |control_event| -> ServiceControlHandlerResult {
|
let event_handler = move |control_event| -> ServiceControlHandlerResult {
|
||||||
match control_event {
|
match control_event {
|
||||||
|
ServiceControl::SessionChange(session) => {
|
||||||
|
info!(
|
||||||
|
"Session Changed: {}",
|
||||||
|
match session.reason {
|
||||||
|
SessionChangeReason::ConsoleConnect => "Console Connect",
|
||||||
|
SessionChangeReason::ConsoleDisconnect => "Console Disconnect",
|
||||||
|
SessionChangeReason::RemoteConnect => "Remote Connect",
|
||||||
|
SessionChangeReason::RemoteDisconnect => "Remote Disconnect",
|
||||||
|
SessionChangeReason::SessionLogon => "Session Logon",
|
||||||
|
SessionChangeReason::SessionLogoff => "Session Logoff",
|
||||||
|
SessionChangeReason::SessionLock => "Session Lock",
|
||||||
|
SessionChangeReason::SessionUnlock => "Session Unlock",
|
||||||
|
SessionChangeReason::SessionRemoteControl => "Session Remote Control",
|
||||||
|
SessionChangeReason::SessionCreate => "Session Create",
|
||||||
|
SessionChangeReason::SessionTerminate => "Session Terminate",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ServiceControlHandlerResult::NoError
|
||||||
|
}
|
||||||
ServiceControl::Interrogate => ServiceControlHandlerResult::NoError,
|
ServiceControl::Interrogate => ServiceControlHandlerResult::NoError,
|
||||||
ServiceControl::Stop => {
|
ServiceControl::Stop => {
|
||||||
shutdown_send.send(()).unwrap();
|
shutdown_send.send(()).unwrap();
|
||||||
@@ -66,7 +89,7 @@ fn service_main(_: Vec<OsString>) {
|
|||||||
.set_service_status(ServiceStatus {
|
.set_service_status(ServiceStatus {
|
||||||
service_type: ServiceType::OWN_PROCESS,
|
service_type: ServiceType::OWN_PROCESS,
|
||||||
current_state: ServiceState::Running,
|
current_state: ServiceState::Running,
|
||||||
controls_accepted: ServiceControlAccept::STOP,
|
controls_accepted: ServiceControlAccept::STOP | ServiceControlAccept::SESSION_CHANGE,
|
||||||
exit_code: ServiceExitCode::Win32(0),
|
exit_code: ServiceExitCode::Win32(0),
|
||||||
checkpoint: 0,
|
checkpoint: 0,
|
||||||
wait_hint: Duration::default(),
|
wait_hint: Duration::default(),
|
||||||
@@ -99,32 +122,45 @@ fn service_main(_: Vec<OsString>) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
fn init_logger() -> Handle {
|
||||||
fn main() -> anyhow::Result<(), windows_service::Error> {
|
use log::LevelFilter;
|
||||||
use log::{debug, info, LevelFilter};
|
use log4rs::{
|
||||||
use log4rs::{append::{console::ConsoleAppender, file::FileAppender}, config::{Appender, Logger, Root}, encode::pattern::PatternEncoder, Config};
|
append::{console::ConsoleAppender, file::FileAppender},
|
||||||
|
config::{Appender, Root},
|
||||||
|
encode::pattern::PatternEncoder,
|
||||||
|
Config,
|
||||||
|
};
|
||||||
|
|
||||||
let stdout = ConsoleAppender::builder().build();
|
let stdout_appender = ConsoleAppender::builder().build();
|
||||||
|
|
||||||
let log_file_path = std::env::current_exe().unwrap().with_file_name("service.log");
|
let log_file_path = std::env::current_exe()
|
||||||
|
.unwrap()
|
||||||
|
.with_file_name("service.log");
|
||||||
|
|
||||||
let requests = FileAppender::builder()
|
let log_file_appender = FileAppender::builder()
|
||||||
.encoder(Box::new(PatternEncoder::default()))
|
.encoder(Box::new(PatternEncoder::new(
|
||||||
|
"{date} {level} {target} - {message}{n}",
|
||||||
|
)))
|
||||||
.build(log_file_path)
|
.build(log_file_path)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let config = Config::builder()
|
let config = Config::builder()
|
||||||
.appender(Appender::builder().build("stdout", Box::new(stdout)))
|
.appender(Appender::builder().build("stdout", Box::new(stdout_appender)))
|
||||||
.appender(Appender::builder().build("requests", Box::new(requests)))
|
.appender(Appender::builder().build("logfile", Box::new(log_file_appender)))
|
||||||
.logger(Logger::builder().build("app::backend::db", LevelFilter::Debug))
|
.build(
|
||||||
.logger(Logger::builder()
|
Root::builder()
|
||||||
.appender("requests")
|
.appender("stdout")
|
||||||
.additive(false)
|
.appender("logfile")
|
||||||
.build("app::requests", LevelFilter::Info))
|
.build(LevelFilter::Trace),
|
||||||
.build(Root::builder().appender("stdout").appender("requests").build(LevelFilter::Trace))
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let handle = log4rs::init_config(config).unwrap();
|
log4rs::init_config(config).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn main() -> anyhow::Result<(), windows_service::Error> {
|
||||||
|
let _ = init_logger();
|
||||||
|
|
||||||
let args = std::env::args().collect::<Vec<_>>();
|
let args = std::env::args().collect::<Vec<_>>();
|
||||||
let command = args.get(1);
|
let command = args.get(1);
|
||||||
@@ -153,11 +189,11 @@ fn main() -> anyhow::Result<(), windows_service::Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Starting service");
|
info!("Starting service");
|
||||||
match service_dispatcher::start(SERVICE_NAME, ffi_service_main) {
|
match service_dispatcher::start(SERVICE_NAME, ffi_service_main) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Error starting service: {:?}", e);
|
info!("Error starting service: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -181,8 +217,10 @@ fn install_service(rules_path: Option<&str>) -> windows_service::Result<()> {
|
|||||||
account_name: None, // run as System
|
account_name: None, // run as System
|
||||||
account_password: None,
|
account_password: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let service = service_manager.create_service(&service_info, ServiceAccess::CHANGE_CONFIG)?;
|
let service = service_manager.create_service(&service_info, ServiceAccess::CHANGE_CONFIG)?;
|
||||||
service.set_description(SERVICE_DESCRIPTION)?;
|
service.set_description(SERVICE_DESCRIPTION)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user