加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 从服务获取登录的用户名

发布时间:2020-12-16 01:41:51 所属栏目:百科 来源:网络整理
导读:我有一项服务,我必须登录到本地管理员进行安装.当用户登录或注销以记录其用户名时,此服务的目的是记录.我终于找到了一些我认为可行的WMI代码,但它仍然是返回管理员.为什么这不起作用? var query = new ObjectQuery("SELECT * FROM Win32_Process WHERE Name
我有一项服务,我必须登录到本地管理员进行安装.当用户登录或注销以记录其用户名时,此服务的目的是记录.我终于找到了一些我认为可行的WMI代码,但它仍然是返回管理员.为什么这不起作用?

var query = new ObjectQuery("SELECT * FROM Win32_Process WHERE Name = 'explorer.exe'");
var explorerProcesses = new ManagementObjectSearcher(query).Get();

foreach (ManagementObject mo in explorerProcesses)
{
    string[] ownerInfo = new string[2];
    mo.InvokeMethod("GetOwner",(object[])ownerInfo);

    userName = String.Concat(ownerInfo[1],@"",ownerInfo[0]);
}
Console.WriteLine(userName);
Console.ReadLine();

为了澄清我的问题,我想要获得当前登录的用户,但是它给了我管理员我用来安装服务的帐户.

解决方法

您应该使用服务控制管理器通知.您可以将服务配置为在用户登录和/或注销时接收通知事件.这允许服务在服务需要时进行交互式用户模拟,但它应该为您提供日志记录所需的信息.

请在此处查看“使用服务控制管理器(SCM)通知”部分http://technet.microsoft.com/en-us/library/cc721961(WS.10).aspx

编辑

在Service类中,重写OnSessionChange事件处理程序以检查登录和注销事件.

protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
    base.OnSessionChange(changeDescription);

    switch (changeDescription.Reason)
    {
        case SessionChangeReason.SessionLogon:
            // do your logging here
            break;

        case SessionChangeReason.SessionLogoff:
            // do your logging here
            break;
    }
}

EDIT2:

class Class1
{
    [DllImport("Advapi32.dll")]
    static extern bool GetUserName(StringBuilder lpBuffer,ref int nSize);    
    [STAThread]
    static void Main(string[] args)
    {
        StringBuilder Buffer = new StringBuilder(64);
        int nSize=64;
        GetUserName(Buffer,ref nSize);
        Console.WriteLine(Buffer.ToString());
    }
}

EDIT3:

public class InteractiveUser
{
    [DllImport("wtsapi32.dll",SetLastError = true)]
    static extern bool WTSQueryUserToken(UInt32 sessionId,out IntPtr Token);

    [DllImport("kernel32.dll")]
    private static extern UInt32 WTSGetActiveConsoleSessionId();

    enum TOKEN_INFORMATION_CLASS
    {
        TokenUser = 1,TokenGroups,TokenPrivileges,TokenOwner,TokenPrimaryGroup,TokenDefaultDacl,TokenSource,TokenType,TokenImpersonationLevel,TokenStatistics,TokenRestrictedSids,TokenSessionId,TokenGroupsAndPrivileges,TokenSessionReference,TokenSandBoxInert,TokenAuditPolicy,TokenOrigin
    }

    public struct TOKEN_USER 
    { 
        public SID_AND_ATTRIBUTES User; 
    } 

    [StructLayout(LayoutKind.Sequential)]
    public struct SID_AND_ATTRIBUTES 
    { 
        public IntPtr Sid; 
        public int Attributes; 
    } 

    // Using IntPtr for pSID insted of Byte[]
    [DllImport("advapi32",CharSet=CharSet.Auto,SetLastError=true)]
    static extern bool ConvertSidToStringSid(
        IntPtr pSID,out IntPtr ptrSid);

    [DllImport("kernel32.dll")]
    static extern IntPtr LocalFree(IntPtr hMem);

    [DllImport("advapi32.dll",SetLastError=true)]
    static extern bool GetTokenInformation(
        IntPtr TokenHandle,TOKEN_INFORMATION_CLASS TokenInformationClass,IntPtr TokenInformation,int TokenInformationLength,out int ReturnLength);

    private static string GetSID(IntPtr token)
    {
        bool Result;

        int TokenInfLength = 0; 
        string sidAsString = String.Empty;

        // first call gets lenght of TokenInformation
        Result = GetTokenInformation( token,TOKEN_INFORMATION_CLASS.TokenUser,IntPtr.Zero,TokenInfLength,out TokenInfLength ); 

        IntPtr TokenInformation = Marshal.AllocHGlobal( TokenInfLength ) ; 
        Result = GetTokenInformation( token,TokenInformation,out TokenInfLength ) ; 

        if ( Result ) 
        {
            TOKEN_USER TokenUser = ( TOKEN_USER )Marshal.PtrToStructure( TokenInformation,typeof( TOKEN_USER ) ) ; 

            IntPtr pstr = IntPtr.Zero; 
            Boolean ok = ConvertSidToStringSid( TokenUser.User.Sid,out pstr ); 

            sidAsString = Marshal.PtrToStringAuto( pstr ); 
            LocalFree(pstr);
        }

        Marshal.FreeHGlobal( TokenInformation );

        return sidAsString;
    }

    public static string Account()
    {
        IntPtr token = IntPtr.Zero;
        String account = String.Empty;

        if (WTSQueryUserToken(WTSGetActiveConsoleSessionId(),out token))
        {
            String sid = GetSID(token);
            account =
                new SecurityIdentifier(sid).Translate(typeof(NTAccount)).ToString();
        }
        else
        {
            int err = Marshal.GetLastWin32Error();
            switch (err)
            {
                case 5:
                    account = "ERROR_ACCESS_DENIED";
                    break;
                case 87:
                    account = "ERROR_INVALID_PARAMETER";
                    break;
                case 1008:
                    account = "ERROR_NO_TOKEN";
                    break;
                case 1314:
                    account = "ERROR_PRIVILEGE_NOT_HELD";
                    break;
                case 7022:
                    account = "ERROR_CTX_WINSTATION_NOT_FOUND";
                    break;
                default:
                    account = String.Format("ERROR_{0}",err.ToString());
                    break;
            }
        }

        return account;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读