タイトルで述べたように、クラスSessionSwitch
のイベントの受信に問題があります。SystemEvents
SystemEvents クラスのドキュメンテーション ページの最後にサンプル コード ( Example 2 ) があり、イベントを受け取る方法を示しており、うまく機能TimeChanged
しUserPreferencesChanged
ます。
自分用に別のイベント ハンドラーを追加しましSessionSwitch
た。私が理解したように、ウィンドウを持つアプリケーションのみが OS からこのメッセージを受け取ることができます (メッセージ ループがあるため)。そのため、この例には非表示のウィンドウがあります。アプリを作成しようとしましたがWinForms
、問題なく動作するため、コードは正しいです。しかし、 のWindows Service
下で実行される が必要Local System Account
です。何が問題なのかわかりません。
Visual Studio 2012 Ultimate と Windows 7 Enterprise Edition を使用しています。
コード:
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);
}
}
}