Как захватить событие выхода из системы с помощью службы Windows в C #? - PullRequest
1 голос
/ 23 февраля 2010

Я пытаюсь создать службу, которая будет входить в систему при входе и выходе из системы. У меня нет проблем с регистрацией входа в систему, но по какой-то причине я не могу поймать событие выхода из системы. это код, который я использовал:

protected override void OnStart(string[] args)
{
    //SystemEvents.SessionSwitch +=    new SessionSwitchEventHandler(SystemEvents_SessionSwitch);
    SystemEvents.SessionEnding += new SessionEndingEventHandler(SystemEvents_SessionEnding);
}
void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
{
    this.EventLog.WriteEntry("We have cought logout event");
    sendData("off");
}

Я пытался использовать SessionEnding, SessionEnded и SessionSwitch, но, похоже, ни один из них не работает. Я проверил службу, она запущена и работает, а служба работает под учетной записью локальной системы и отмечена опция «Разрешить службе взаимодействовать с рабочим столом»

Есть предложения?

Класс обслуживания:

public partial class Service1 : ServiceBase
{
    public Service1()
    {
        InitializeComponent();
    }
    protected override void OnStart(string[] args)
    {
        EventLog.WriteEntry("WinSendSED", "Starting WinSendSED");
        new Thread(RunMessagePump).Start();
    }
    void RunMessagePump()
    {
        EventLog.WriteEntry("WinSendSED.MessagePump", "Starting WinSendSED Message Pump");
        Application.Run(new HiddenForm());
    }
    protected override void OnStop()
    {
        //sendData("off");
        Application.Exit();
    }
}

Скрытая форма:

public partial class HiddenForm : Form
{
    public HiddenForm()
    {
        InitializeComponent();
    }
    private string makeNiceMAC(string s)
    {
        for (int i = 0; i < 5; i++)
        {
            s = s.Insert((3 * i) + 2, "-");
        }
        return s;
    }
    private string getUserName()
    {
        Process[] ps = Process.GetProcesses();
        foreach (Process p in ps)
        {
            if (p.ProcessName.Trim() == "explorer")
            {
                ObjectQuery sq = new ObjectQuery
                    ("Select * from Win32_Process Where ProcessID = '" + p.Id + "'");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(sq);
                foreach (ManagementObject oReturn in searcher.Get())
                {
                    string[] o = new String[2];
                    oReturn.InvokeMethod("GetOwner", (object[])o);
                    return o[0];
                }
            }
        }
        return "";
    }
    private string GetIPAddress()
    {
        IPAddress[] addr = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
        for (int i = 0; i < addr.Length; i++)
        {
            if (addr[i].ToString().Contains("."))
                return addr[i].ToString();
        }
        return "127.0.0.1";
    }
    private string printData()
    {
        WindowsIdentity id = WindowsIdentity.GetCurrent();
        NetworkInterface[] nis = NetworkInterface.GetAllNetworkInterfaces();
        NetworkInterface ni = nis[0];
        foreach (NetworkInterface nii in nis)
        {
            if ((nii.OperationalStatus == OperationalStatus.Up)
                && (!nii.GetPhysicalAddress().ToString().EndsWith("000000E0"))
                && (nii.GetPhysicalAddress().ToString().Length > 5))
            {
                ni = nii;
            }
        }
        string line = "";
        line = line + "'" + makeNiceMAC(ni.GetPhysicalAddress().ToString()) + "', ";
        line = line + "'" + GetIPAddress() + "', ";
        line = line + "'" + getUserName() + "'";
        return line;
    }
    private void sendData(string cmd)
    {
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        IPEndPoint ipAdd = new IPEndPoint(IPAddress.Parse(//"127.0.0.1"), 2345);
            "123.123.123.123"), 2345);
        try
        {
            s.Connect(ipAdd);
            String szData = cmd + printData();
            byte[] byData = System.Text.Encoding.ASCII.GetBytes(szData);
            s.Send(byData);
            s.Close();
        }
        catch (SocketException se)
        {
            s.Close();
        }
    }

    private void HiddenForm_Load(object sender, EventArgs e)
    {
        SystemEvents.SessionEnding += 
            new SessionEndingEventHandler(SystemEvents_SessionEnding);
    }

    void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
    {
        EventLog.WriteEntry("WinSendSED", "We have cought logout event");
        sendData("off");
    }

    private void HiddenForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        SystemEvents.SessionEnding -= 
            new SessionEndingEventHandler(SystemEvents_SessionEnding);
    }

    private System.ComponentModel.IContainer components = null;

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    private void InitializeComponent()
    {
        this.SuspendLayout();
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(0, 0);
        this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        this.Name = "HiddenForm";
        this.Text = "HiddenForm";
        this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
        this.Load += new System.EventHandler(this.HiddenForm_Load);
        this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.HiddenForm_FormClosing);
        this.ResumeLayout(false);

    }
}

1 Ответ

1 голос
/ 23 февраля 2010

Как насчет использования групповой политики? Вы можете запустить процесс по событию выхода из системы, если вы используете групповую политику локального компьютера.

...