Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从服务中获取登录系统的用户数_C#_Windows Services - Fatal编程技术网

C# 从服务中获取登录系统的用户数

C# 从服务中获取登录系统的用户数,c#,windows-services,C#,Windows Services,我想从Windows服务(本地系统帐户)中了解系统上登录用户的数量,我已在Windows服务上实现了此方法: protected override void OnSessionChange(SessionChangeDescription changeDescription) { base.OnSessionChange(changeDescription); switch (changeDescription.Reason) {

我想从Windows服务(本地系统帐户)中了解系统上登录用户的数量,我已在Windows服务上实现了此方法:

  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;
        }
    }
问题是,如果我从用户会话而不是在系统启动时手动启动此服务,变量userCount=0,而当我启动服务时,有一个用户登录?如何在给定时刻获取系统上已登录用户的号码?
有办法吗?

您可以p/调用LsaEnumerateLogonSessions():

如果函数成功,第一个参数将包含登录用户的计数。应立即使用LsaFreeReturnBuffer()释放第二个参数中返回的LUID数组,以避免泄漏


EDIT:LsaEnumerateLogonSessions()还返回非交互式会话,因此您需要对每个LUID调用LsaGetLogonSessionData(),以检查其是否为交互式会话。所以最好像埃米什建议的那样使用WMI,因为您不必迭代IntPtr。虽然算法保持不变。

这是一个老话题,但我想发布这个,以防任何人需要其他信息。我发现这篇文章展示了如何使用LsaEnumerateLogonSessions,以及我使用System.Management的代码。

对于LsaEnumerateLogonSessions:


对于系统管理:

    System.Management.ConnectionOptions connOptions = new System.Management.ConnectionOptions();
    System.Collections.Generic.List<string> sessionIDs = new System.Collections.Generic.List<string>();

    connOptions.Impersonation = System.Management.ImpersonationLevel.Impersonate;
    connOptions.EnablePrivileges = true;

    try
    {

        //Use "." for the local computer, or a computer name or IP address for a remote computer.
        string compName = ".";
        System.Management.ManagementScope manScope =
            new System.Management.ManagementScope(
                String.Format(@"\\{0}\ROOT\CIMV2", compName), connOptions);
        manScope.Connect();

        System.Management.SelectQuery selectQuery = new System.Management.SelectQuery("Select SessionId from Win32_Process");

        using (System.Management.ManagementObjectSearcher searcher =
        new System.Management.ManagementObjectSearcher(manScope, selectQuery))
        {
            foreach (System.Management.ManagementObject proc in searcher.Get())
            {
                string id = proc["SessionId"].ToString();
                //Skip session 0, which is the system session.
                if (id != "0")
                {
                    sessionIDs.Add(id);
                }
            }
        }

        //remove the dups.
        sessionIDs = sessionIDs.Distinct().ToList();

        foreach (string id in sessionIDs)
        {
            System.Diagnostics.Debug.Print(id);
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print(ex.Message);
    }
System.Management.ConnectionOptions connpoptions=new System.Management.ConnectionOptions();
System.Collections.Generic.List sessionIDs=new System.Collections.Generic.List();
connOptions.Impersonation=System.Management.ImpersonationLevel.Impersonate;
connpoptions.EnablePrivileges=true;
尝试
{
//本地计算机使用“.”,远程计算机使用计算机名或IP地址。
字符串compName=“.”;
System.Management.ManagementScope手动示波器=
新系统。管理。管理范围(
格式(@“\{0}\ROOT\CIMV2”,compName),connpoptions);
manScope.Connect();
System.Management.SelectQuery SelectQuery=new System.Management.SelectQuery(“从Win32_进程中选择会话ID”);
使用(System.Management.ManagementObjectSearcher)搜索器=
新系统。管理。管理对象搜索器(manScope,selectQuery))
{
foreach(searcher.Get()中的System.Management.ManagementObject进程)
{
字符串id=proc[“SessionId”].ToString();
//跳过会话0,它是系统会话。
如果(id!=“0”)
{
sessionIDs.Add(id);
}
}
}
//移除DUP。
sessionIDs=sessionIDs.Distinct().ToList();
foreach(sessionid中的字符串id)
{
系统.诊断.调试.打印(id);
}
}
捕获(例外情况除外)
{
系统、诊断、调试、打印(例如消息);
}

我在系统上只有一个登录用户,logonSessionCount返回我6。。。为什么?@aleroot,看起来非交互式会话也会返回。您可以使用LsaGetLogonSessionData()筛选会话列表,但仅获取用户计数就变得非常复杂…请检查该方法的文档,可能该计数包括除交互登录类型以外的其他登录类型,如服务、网络等。
    System.Management.ConnectionOptions connOptions = new System.Management.ConnectionOptions();
    System.Collections.Generic.List<string> sessionIDs = new System.Collections.Generic.List<string>();

    connOptions.Impersonation = System.Management.ImpersonationLevel.Impersonate;
    connOptions.EnablePrivileges = true;

    try
    {

        //Use "." for the local computer, or a computer name or IP address for a remote computer.
        string compName = ".";
        System.Management.ManagementScope manScope =
            new System.Management.ManagementScope(
                String.Format(@"\\{0}\ROOT\CIMV2", compName), connOptions);
        manScope.Connect();

        System.Management.SelectQuery selectQuery = new System.Management.SelectQuery("Select SessionId from Win32_Process");

        using (System.Management.ManagementObjectSearcher searcher =
        new System.Management.ManagementObjectSearcher(manScope, selectQuery))
        {
            foreach (System.Management.ManagementObject proc in searcher.Get())
            {
                string id = proc["SessionId"].ToString();
                //Skip session 0, which is the system session.
                if (id != "0")
                {
                    sessionIDs.Add(id);
                }
            }
        }

        //remove the dups.
        sessionIDs = sessionIDs.Distinct().ToList();

        foreach (string id in sessionIDs)
        {
            System.Diagnostics.Debug.Print(id);
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print(ex.Message);
    }