As I mentioned in title I have a problem with receiving SessionSwitch
events of SystemEvents
class.
There is a sample code (Example 2) at the end of SystemEvents class documentation page which shows how to receive TimeChanged
and UserPreferencesChanged
events and it works good.
I have added another event handler for SessionSwitch
by myself. As I figured out only applications with window can receive this message from OS (because only they have message loop). That is why there is hidden window in this example. I have tried to create WinForms
app and it works okay so the code is correct. But I need a Windows Service
which will be running under Local System Account
. I have no ideas what is the problem.
I am using Visual Studio 2012 Ultimate and Windows 7 Enterprise Edition.
Code:
using System;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.Drawing;
using System.ServiceProcess;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
namespace SimpleServiceCs
{
public class SimpleService : ServiceBase
{
private static void Main(string[] args)
{
Run(new SimpleService());
}
protected override void OnStart(string[] args)
{
EventLog.WriteEntry("SimpleService", "Starting SimpleService");
new Thread(RunMessagePump).Start();
}
private void RunMessagePump()
{
EventLog.WriteEntry("SimpleService.MessagePump", "Starting SimpleService Message Pump");
Application.Run(new HiddenForm());
}
protected override void OnStop()
{
Application.Exit();
}
}
public partial class HiddenForm : Form
{
public HiddenForm()
{
InitializeComponent();
}
private void HiddenForm_Load(object sender, EventArgs e)
{
SystemEvents.TimeChanged += SystemEvents_TimeChanged;
SystemEvents.UserPreferenceChanged += SystemEvents_UPCChanged;
SystemEvents.SessionSwitch +=SystemEvents_SessionSwitch;
}
private void HiddenForm_FormClosing(object sender, FormClosingEventArgs e)
{
SystemEvents.TimeChanged -= SystemEvents_TimeChanged;
SystemEvents.UserPreferenceChanged -= SystemEvents_UPCChanged;
SystemEvents.SessionSwitch -= SystemEvents_SessionSwitch;
}
private void SystemEvents_TimeChanged(object sender, EventArgs e)
{
EventLog.WriteEntry("SimpleService.TimeChanged", "Time changed; it is now " +
DateTime.Now.ToLongTimeString());
}
private void SystemEvents_UPCChanged(object sender, UserPreferenceChangedEventArgs e)
{
EventLog.WriteEntry("SimpleService.UserPreferenceChanged", e.Category.ToString());
}
private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
{
switch (e.Reason)
{
case SessionSwitchReason.ConsoleConnect:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Connected from console at " + DateTime.Now.ToLongTimeString());
break;
case SessionSwitchReason.ConsoleDisconnect:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Disconnected from console at " + DateTime.Now.ToLongTimeString());
break;
case SessionSwitchReason.RemoteConnect:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Connected from remote at " + DateTime.Now.ToLongTimeString());
break;
case SessionSwitchReason.RemoteDisconnect:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Disconnected from remote at " + DateTime.Now.ToLongTimeString());
break;
case SessionSwitchReason.SessionLock:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Locked at " + DateTime.Now.ToLongTimeString());
break;
case SessionSwitchReason.SessionLogoff:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Logoff at " + DateTime.Now.ToLongTimeString());
break;
case SessionSwitchReason.SessionLogon:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Logon at " + DateTime.Now.ToLongTimeString());
break;
case SessionSwitchReason.SessionRemoteControl:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Remote control at " + DateTime.Now.ToLongTimeString());
break;
case SessionSwitchReason.SessionUnlock:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Unlocked at " + DateTime.Now.ToLongTimeString());
break;
default:
EventLog.WriteEntry("SimpleService.SessionSwitch",
"Default case: something is wrong. " + DateTime.Now.ToLongTimeString(),
EventLogEntryType.Error);
break;
}
}
}
partial class HiddenForm
{
private readonly IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
SuspendLayout();
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(0, 0);
FormBorderStyle = FormBorderStyle.None;
Name = "HiddenForm";
Text = "HiddenForm";
WindowState = FormWindowState.Minimized;
Load += HiddenForm_Load;
FormClosing += HiddenForm_FormClosing;
ResumeLayout(false);
}
}
[RunInstaller(true)]
public class SimpleInstaller : Installer
{
private ServiceProcessInstaller processInstaller;
private ServiceInstaller serviceInstaller;
public SimpleInstaller()
{
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();
// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;
// Service will have Start Type of Manual
serviceInstaller.StartType = ServiceStartMode.Automatic;
serviceInstaller.ServiceName = "Simple Service";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}