正如我在标题中提到的,我在接收类SessionSwitch
事件时遇到问题SystemEvents
。
SystemEvents 类文档页面的末尾有一个示例代码(示例 2TimeChanged
),它显示了如何接收和UserPreferencesChanged
事件,并且效果很好。
我自己添加了另一个事件处理程序SessionSwitch
。我发现只有带有窗口的应用程序才能从操作系统接收到这条消息(因为只有它们有消息循环)。这就是本例中隐藏窗口的原因。我试图创建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);
}
}
}