如何使用Windows服务在文本文件中写入登录的用户名! [英] How to write logged in UserName in text file using windows service!!

查看:66
本文介绍了如何使用Windows服务在文本文件中写入登录的用户名!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码进行服务

I am using the following code for the service

namespace WindowsService
{
    public partial class MyWinService : ServiceBase
    {
        public MyWinService()
        {
            InitializeComponent();
            if (!System.Diagnostics.EventLog.SourceExists("DoLogSource"))
                System.Diagnostics.EventLog.CreateEventSource("DoLogSource", "LogSource");
            eventLog1.Source = "DoLogSource";
            eventLog1.Log = "LogSource";
        }

        protected override void OnStart(string[] args)
        {

            FileStream fs = new FileStream(@"c:\cWindowsService.txt",
            FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter m_streamWriter = new StreamWriter(fs);
            m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
            m_streamWriter.WriteLine("mcWindowsService: Service Started \n");
            m_streamWriter.Flush();
            m_streamWriter.Close(); 
            ManagementClass mc = new ManagementClass("Win32_Process");
            ManagementObjectCollection moc = mc.GetInstances();
            //ManagementObject mo = default(ManagementObject);
            string processDomain = null;
            string processUser = null;
            foreach(ManagementObject mo in moc)
            {
               ROOT.CIMV2.Process p = new ROOT.CIMV2.Process(mo);

               p.GetOwner(out processDomain, out processUser);
                if ((p.Name.ToString().Trim() == "explorer.exe"))
                {
                    System.Diagnostics.TextWriterTraceListener myfile = new System.Diagnostics.TextWriterTraceListener("C:\\UserName.txt");
                    Trace.Listeners.Add(myfile);
                    myfile.WriteLine(processUser);
                    m_streamWriter.WriteLine("Logged in User: "+processUser+"\n");
                    break;
                }
            }

        }

推荐答案

嗨.
这是我对您问题的回答:
您能请我解释一下如何获得用户名吗?"为了获得必要的结果,您需要使用WinApi和P/Invoke.
常规工作流程将是下一个:

1)调用WTSGetActiveConsoleSessionId()以获取活动的控制台会话ID(非常重要,因为交互式会话并不总是会话1,即使在客户端系统上也是如此).如果没有活动用户登录到交互式会话(也就是说,与使用RDP相对,则本地登录到物理计算机,则该API还将返回-1).
2)将会话ID从上一个API调用传递到WTSQueryUserToken(),以获取一个开放令牌,该令牌表示已登录控制台的用户.
3)调用DuplicateTokenEx()将模拟令牌(从WTSQueryUserToken转换为主要令牌).
4)调用CreateEnvironmentBlock()为该进程创建一个新环境(可选,但如果没有,则该进程将没有一个).
5)使用第3步中的主要用户令牌模拟用户并模拟用户:
Hi.
This is my answer to yours question:
"Can u kindly explain how may I get the user name??" For reaching necessary result you need to use WinApi and P/Invoke.
General workflow will be the next:

1) Call WTSGetActiveConsoleSessionId() to get the active console session id (VERY important, as the interactive session is NOT always session 1, even on client systems). This API will also return a -1 if there is no active user logged into the interactive session (that is, logged in locally to the physical machine, as opposed to using RDP).
2) Pass the session id from the previous API call to WTSQueryUserToken() to get an open token that reprents the user logged into the console.
3) Call DuplicateTokenEx() to convert the impersonation token (from WTSQueryUserToken) into a primary token.
4) Call CreateEnvironmentBlock() to create a new environment for the process (optional, but if you don''t, the process won''t have one).
5)Impersonate user using primary user token from step #3 and impersonate user:
WindowsIdentity tempWindowsIdentity = new WindowsIdentity(tokenDuplicate.DangerousGetHandle());
 impersonationContext = tempWindowsIdentity.Impersonate();



5)调用方法GetProcessInfoByPID(....)*请参阅解决方案中的内容*

6)如果创建了环境块,则需要调用DestroyEnvironmentBlock,否则会产生内存泄漏.启动该过程时,会为其分配环境块的单独副本,因此您只破坏了本地数据.



5) Invoke Method GetProcessInfoByPID(....) *see in the of solution*

6)If you created an environment block, then you need to call DestroyEnvironmentBlock, otherwise you will generate a memory leak. The process is given a separate copy of the environment block when it launches, so you are only destroying local data.

public static string GetProcessInfoByPID(int PID, out string User, out string Domain)
{
    User = String.Empty;
    Domain = String.Empty;
    OwnerSID = String.Empty;
    string processname = String.Empty;
    try
    {
        ObjectQuery sq = new ObjectQuery
            ("Select * from Win32_Process Where ProcessID = '" + PID + "'");
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(sq);
        if (searcher.Get().Count == 0)
            return OwnerSID;
        foreach (ManagementObject oReturn in searcher.Get())
        {
            string[] o = new String[2];
            //Invoke the method and populate the o var with the user name and domain
            oReturn.InvokeMethod("GetOwner", (object[])o);

            //int pid = (int)oReturn["ProcessID"];
            processname = (string)oReturn["Name"];
            //dr[2] = oReturn["Description"];
            User = o[0];
            if (User == null)
                User = String.Empty;
            Domain = o[1];
            if (Domain == null)
                Domain = String.Empty;
            string[] sid = new String[1];
            oReturn.InvokeMethod("GetOwnerSid", (object[])sid);
            OwnerSID = sid[0];
     return OwnerSID;
        }
    }
    catch
    {
        return OwnerSID;
    }
    return OwnerSID;
}


这篇关于如何使用Windows服务在文本文件中写入登录的用户名!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆