public SystemEventNotifier(int maxIdleSeconds = 60 * 15) { _cts = new CancellationTokenSource(); _ct = _cts.Token; this._maxIdleSeconds = maxIdleSeconds; Display = X11.Xlib.XOpenDisplay(null); xsi = new X11.XScreenSaverInfo(); lastCheck = DateTime.Now; _pollTask = new Task(() => { Log.Information("SystemEventNotifier polling task started"); while (!_ct.IsCancellationRequested) { // Check system idle time X11.Xlib.XScreenSaverQueryInfo(Display, X11.Xlib.XRootWindow(Display, 0), ref xsi); Log.Debug("Idle time: {IdleTime}", xsi.idle.ToString()); if ((xsi.idle / 1000) > (ulong)_maxIdleSeconds) { if (!_idleDetected) { Idle?.Invoke(this, new SystemEventArgs("Idle Timeout")); Log.Information("Detected idle timeout"); _idleDetected = true; } } else { if (_idleDetected) { _idleDetected = false; } } if ((ScreenSaverState)xsi.state == ScreenSaverState.ScreenSaverOn) { if (!_screenSaver) { Screensaver?.Invoke(this, new SystemEventArgs("Screen Saver")); Log.Information("Detected Screen Saver On"); _screenSaver = true; } } else if (_screenSaver) { _screenSaver = false; } //Since we can't check for Lock, Logout or Restart we are going to //Do a bit of a hack and assume that if our loop took longer than triple the standard time to run //then we want to go ahead and clear the quick pass; if ((DateTime.Now - lastCheck).TotalSeconds > (POLL_INTERVAL / 1000) * 3) { Log.Information("Detected an Anommaly System Loop took > 3X to run, clearing quick pass"); Standby?.Invoke(this, new SystemEventArgs("System Hiccup Clearing QuickPass Just in Case")); } lastCheck = DateTime.Now; Thread.Sleep(POLL_INTERVAL); } Log.Information("SystemEventNotifier polling task ending"); }, _ct); _pollTask.Start(); }
public IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { Log.Debug("SystemEventNotifier WndProc: MSG={Msg}, wParam={wParam}, lParam={lParam}", ((UnmanagedMethods.WindowsMessage)msg).ToString(), ((UnmanagedMethods.WindowsMessage)wParam.ToInt32()).ToString(), ((UnmanagedMethods.WindowsMessage)lParam.ToInt32()).ToString()); switch (msg) { case (uint)UnmanagedMethods.WindowsMessage.WM_WTSSESSION_CHANGE: switch (wParam.ToInt32()) { case UnmanagedMethods.WTS_SESSION_LOGOFF: SessionLogoff?.Invoke(this, new SystemEventArgs("Session Logoff")); Log.Information("Detected session logoff"); break; case UnmanagedMethods.WTS_SESSION_LOCK: SessionLock?.Invoke(this, new SystemEventArgs("Session Lock")); Log.Information("Detected session lock"); break; } break; case (uint)UnmanagedMethods.WindowsMessage.WM_ENDSESSION: // If the session is being ended, the wParam parameter is TRUE; // the session can end any time after all applications have returned // from processing this message. Otherwise, it is FALSE. if (wParam.ToInt32() == 0) { break; } switch (lParam.ToInt32()) { case 0: //Shutdown or restart ShutdownOrRestart?.Invoke(this, new SystemEventArgs("System Shutdown/Restart")); Log.Information("Detected system shutdown/restart"); break; case UnmanagedMethods.ENDSESSION_LOGOFF: case UnmanagedMethods.ENDSESSION_CLOSEAPP: case UnmanagedMethods.ENDSESSION_CRITICAL: SessionLogoff?.Invoke(this, new SystemEventArgs("Session Ending")); Log.Information("Detected end of session"); break; } break; case (uint)UnmanagedMethods.WindowsMessage.WM_POWERBROADCAST: switch (wParam.ToInt32()) { case UnmanagedMethods.PBT_APMSUSPEND: case UnmanagedMethods.PBT_APMSTANDBY: Standby?.Invoke(this, new SystemEventArgs("Standby")); Log.Information("Detected entering sleep mode"); break; } break; default: break; } return(IntPtr.Zero); }
/// <summary> /// Creates a new <c>SystemEventNotifier</c> instance and sets up some /// required resources. /// </summary> /// <param name="maxIdleSeconds">The maximum system idle time in seconds before the /// <c>Idle</c> event is being raised.</param> public SystemEventNotifier(int maxIdleSeconds = 60 * 15) { Log.Information($"Instanciating System Event Notifier"); _cts = new CancellationTokenSource(); _ct = _cts.Token; this._maxIdleSeconds = maxIdleSeconds; //Subscribe to an apple notification fired when the screen is locked ((NSDistributedNotificationCenter)NSDistributedNotificationCenter.DefaultCenter).AddObserver(new NSString("com.apple.screenIsLocked"), (obj) => { Log.Information("Detected session lock"); SessionLock?.Invoke(this, new SystemEventArgs("Session Lock")); }); //Subscribe to an apple notification fired when the screen saver starts ((NSDistributedNotificationCenter)NSDistributedNotificationCenter.DefaultCenter).AddObserver(new NSString("com.apple.screensaver.didstart"), (obj) => { Log.Information("Detected Screen Saver"); Screensaver?.Invoke(this, new SystemEventArgs("Screensaver")); }); //Subscribe to an apple notification fired when the System goes to Sleep NSWorkspace.Notifications.ObserveWillSleep((s, e) => { Log.Information("Detected Standy"); Standby?.Invoke(this, new SystemEventArgs("Stand By")); }); //Subscribe to an apple notification fired when the System goes to power off / reboot NSWorkspace.Notifications.ObserveWillPowerOff((s, e) => { Log.Information("Detected PowerOff / Reboot"); ShutdownOrRestart?.Invoke(this, new SystemEventArgs("System ShutDown / Reboot")); }); //Subscribe to an apple notification fired when the System goes to Log off the current User NSWorkspace.Notifications.ObserveSessionDidResignActive((s, e) => { Log.Information("Detected PowerOff / Reboot"); SessionLogoff?.Invoke(this, new SystemEventArgs("Session Log Off")); }); // Start a task to poll Idle Time Global Environment Variable _pollTask = new Task(() => { Log.Information("SystemEventNotifier polling task started"); Thread.Sleep(POLL_INTERVAL); //Sleep at first to give Mac Delegate time while (!_ct.IsCancellationRequested) { // Check system idle time TimeSpan idletime = AppDelegate.CheckIdleTime(); Log.Debug("Idle time: {IdleTime}", idletime.ToString()); if (idletime.TotalSeconds > _maxIdleSeconds) { if (!_idleDetected) { Idle?.Invoke(this, new SystemEventArgs("Idle Timeout")); Log.Information("Detected idle timeout"); _idleDetected = true; } } else { if (_idleDetected) { _idleDetected = false; } } Thread.Sleep(POLL_INTERVAL); } Log.Information("SystemEventNotifier polling task ending"); }, _ct); _pollTask.Start(); Log.Information($"System Event Notifier was Innitialized Successfully"); }
/// <summary> /// Return to standby mode /// </summary> /// <param name="sender">Event source</param> /// <param name="e">Event args</param> private void FileStandby_Click(object sender, EventArgs args) { Standby?.Invoke(this, args); }