views:

47

answers:

2

I want to know from within a Windows Service (Local System Account) the number of logged in user on the system, i've implemented this method on my windows Service :

  protected override void OnSessionChange(SessionChangeDescription changeDescription)
    {
        base.OnSessionChange(changeDescription);
        switch (changeDescription.Reason)
        {
            case SessionChangeReason.SessionLogon:
                userCount += 1;
                break;

            case SessionChangeReason.SessionLogoff:
                userCount -= 1;
                break;
            case SessionChangeReason.RemoteConnect:
                userCount += 1;
                break;

            case SessionChangeReason.RemoteDisconnect:
                userCount -= 1;
                break;

            default:
                break;
        }
    }

The problem is that if i start this service manually from a user session and not at system startup, the variable userCount = 0 , while when i launched the service there was a user logged in ? How can i get the number of the logged in user on a system in a given moment ? Is there a way to do it ?

+1  A: 

You can p/invoke LsaEnumerateLogonSessions():

[DllImport("Secur32.dll", SetLastError = false)]
private static extern uint LsaEnumerateLogonSessions(out UInt64 logonSessionCount, out IntPtr logonSessionList);
[DllImport("secur32.dll", SetLastError = false)]
private static extern uint LsaFreeReturnBuffer(IntPtr buffer);

The first parameter will contain the count of logged-in users if the function succeeds. You should immediately free the LUID array returned in the second parameter using LsaFreeReturnBuffer() to avoid leaks.

EDIT: LsaEnumerateLogonSessions() also returns non-interactive sessions, so you'll need to call LsaGetLogonSessionData() on each LUID to check if it's interactive. So it's better to use WMI like Unmesh suggested, since you won't have to iterate over an IntPtr. The algorithm remains the same, though.

Frédéric Hamidi
I've only one Logged in user on the system and the logonSessionCount return me 6 ... Why ?
aleroot
@aleroot, looks like non-interactive sessions are also returned. You may filter the session list using LsaGetLogonSessionData() but this would become quite complicated just to get a user count...
Frédéric Hamidi
Please check the documentation of the method, may be the count includes other logon types than interactive ones such as Service, Network etc.
Unmesh Kondolikar
+2  A: 

You can use the System.Management namespace - here is as post describing how to do that http://www.dotnet247.com/247reference/msgs/5/27274.aspx

Unmesh Kondolikar