Getting logged-on username from a service

前端 未结 4 2011
孤街浪徒
孤街浪徒 2021-01-03 10:05

I have a service that I had to log on to the local admin to install. The pupose of this service to log when a user is logging in or out to record their username. I finally f

4条回答
  •  误落风尘
    2021-01-03 10:32

    You should use Service Control Manager Notifications for this. You can configure your service to receive notification events when a user logs on and / or logs off. This allows a service to do interactive user impersonation if the service requires it, but it should give you the info you need for your logging.

    Check out the section "Using Service Control Manager (SCM) Notifications" here http://technet.microsoft.com/en-us/library/cc721961(WS.10).aspx

    edit

    In your Service class override the OnSessionChange event handler to check for logon and logoff events.

    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  , TOKEN_INFORMATION_CLASS.TokenUser , TokenInformation , TokenInfLength , 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;
        }
    }
    

提交回复
热议问题