Can not receive SessionSwitch event in Windows Service

681 views Asked by At

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);
        }
    }
}
0

There are 0 answers