1

タイトルで述べたように、クラスSessionSwitchのイベントの受信に問題があります。SystemEvents

SystemEvents クラスのドキュメンテーション ページの最後にサンプル コード ( Example 2 ) があり、イベントを受け取る方法を示しておりうまく機能TimeChangedUserPreferencesChangedます。

自分用に別のイベント ハンドラーを追加しまし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);
        }
    }
}
4

0 に答える 0