2010-02-23 4 views
1

J'essaye de créer un service qui enregistrera quand les utilisateurs ouvriront une session et se déconnecteront. Je n'ai aucun problème avec la capture de la connexion, mais pour une raison quelconque je ne peux pas attraper l'événement de déconnexion. c'est le code que je l'ai utilisé:Comment capturer un événement de déconnexion en utilisant un service Windows en C#?

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

J'ai essayé d'utiliser SessionEnding, SessionEnded et SessionSwitch mais aucun d'entre eux semblent fonctionner. J'ai vérifié le service, il est opérationnel et le serive fonctionne sous le compte du système local et l'option "Autoriser le service à interagir avec le bureau" est cochée.

Des suggestions?

Classe de service:

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

forme cachée:

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

    } 
} 
+0

Avez-vous déjà essayé l'événement OnSessionSwitch? Voir [ce lien] [1]. [1]: http://stackoverflow.com/questions/5353066/how-to-make-a-net-windows-service-detect-logon-logoff-and-switch-user-events –

Répondre

1

Comment l'utilisation de la stratégie de groupe? Vous pouvez lancer un processus sur l'événement de déconnexion, si vous utilisez la stratégie de groupe de la machine locale.

+0

merci pour votre répondre, mon problème est que je ne peux pas attraper l'événement de déconnexion du tout. c'est-à-dire que mon service n'est pas averti lorsque l'événement de déconnexion se produit. –

+0

Je crois qu'il voulait dire l'appel d'un exécutable séparé dans l'événement de déconnexion dans la stratégie de groupe, ce qui fonctionnerait en effet. –

+0

je vois. Mais est-ce la bonne solution si je veux installer le service sur environ 3000 PC? –

Questions connexes