2015-06-10 188 views
0

我的windows服務應該保存用戶的名稱,此刻登錄/註銷。 下面的代碼對我的作品,但沒有保存用戶名:Windows服務:用戶登錄時獲取用戶名

protected override void OnSessionChange(SessionChangeDescription changeDescription) 
    { 
     try 
     { 
      string user = ""; 

      foreach (ManagementObject currentObject in _wmiComputerSystem.GetInstances()) 
      { 
       user += currentObject.Properties["UserName"].Value.ToString().Trim(); 
      } 

      switch (changeDescription.Reason) 
      { 
       case SessionChangeReason.SessionLogon: 
        WriteLog(Constants.LogType.CONTINUE, "Logon - Program continues: " + user); 
        OnContinue(); 
        break; 
       case SessionChangeReason.SessionLogoff: 
        WriteLog(Constants.LogType.PAUSE, "Logoff - Program is paused: " + user); 
        OnPause(); 
        break; 
      } 
      base.OnSessionChange(changeDescription); 
     } 
     catch (Exception exp) 
     { 
      WriteLog(Constants.LogType.ERROR, "Error"); 
     } 
    } 

編輯: foreach循環給我一個錯誤:

Message: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) Type: System.UnauthorizedAccessException

但在我看來,這個代碼是而不是解決方案,因爲它可以保存所有登錄到服務器的用戶。

+0

@Jamiec這就是爲什麼我開了這個問題,得到你覆蓋方法的用戶名。我應該在同一個文本中提出正確答案的問題嗎?該代碼僅用於顯示其他人羣我的代碼看起來如何直到現在 – ZerOne

+0

感謝downvote ..任何評論爲什麼有人downvote ?? – ZerOne

+0

不是我,但是SO的重點不在於爲您編寫代碼,而是爲了幫助您自己完成。你沒有向我們展示任何你已經嘗試過的東西,你完全要求答案。也就是說,也許可以看看Environment.Username。 – bkribbs

回答

0

最後我得到了一個解決方案。在Windows服務方法中,提供了會話ID。因此,通過這個會話ID,我們可以執行一個powershell命令'quser'並獲取當前用戶,在服務器上登錄/註銷。在這裏看到:How to get current windows username from windows service in multiuser environment using .NET

因此,這是功能,這是我們需要創建:

private string GetUsername(int sessionID) 
     { 
      try 
      { 
       Runspace runspace = RunspaceFactory.CreateRunspace(); 
       runspace.Open(); 

       Pipeline pipeline = runspace.CreatePipeline(); 
       pipeline.Commands.AddScript("Quser"); 
       pipeline.Commands.Add("Out-String"); 

       Collection<PSObject> results = pipeline.Invoke(); 

       runspace.Close(); 

       StringBuilder stringBuilder = new StringBuilder(); 
       foreach (PSObject obj in results) 
       { 
        stringBuilder.AppendLine(obj.ToString()); 
       } 

       foreach (string User in stringBuilder.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Skip(1)) 
       { 
        string[] UserAttributes = User.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); 

        if (UserAttributes.Length == 6) 
        { 
         if (int.Parse(UserAttributes[1].Trim()) == sessionID) 
         { 
          return UserAttributes[0].Replace(">", string.Empty).Trim(); 
         } 
        } 
        else 
        { 
         if (int.Parse(UserAttributes[2].Trim()) == sessionID) 
         { 
          return UserAttributes[0].Replace(">", string.Empty).Trim(); 
         } 
        } 
       } 

      } 
      catch (Exception exp) 
      { 
       // Error handling 
      } 

      return "Undefined"; 
     } 

這是窗口服務功能:

protected override void OnSessionChange(SessionChangeDescription changeDescription) 
     { 
      try 
      { 
       switch (changeDescription.Reason) 
       { 
        case SessionChangeReason.SessionLogon: 
         string user = GetUsername(changeDescription.SessionId); 

         WriteLog("Logon - Program continue" + Environment.NewLine + 
          "User: " + user + Environment.NewLine + "Sessionid: " + changeDescription.SessionId); 

         //..... 
1

我遇到了類似的問題,同時建立一個Windows服務。就像你一樣,我有會話ID,需要獲得相應的用戶名。經過幾次不成功的解決方案關於此的話,我跑進this particular answer,它激發了我的解決方案:

這裏是我的代碼(所有的人都居住類內部;在我的情況下,類繼承ServiceBase)。

[DllImport("Wtsapi32.dll")] 
    private static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WtsInfoClass wtsInfoClass, out IntPtr ppBuffer, out int pBytesReturned); 
    [DllImport("Wtsapi32.dll")] 
    private static extern void WTSFreeMemory(IntPtr pointer); 

    private enum WtsInfoClass 
    { 
     WTSUserName = 5, 
     WTSDomainName = 7, 
    } 

    private static string GetUsername(int sessionId, bool prependDomain = true) 
    { 
     IntPtr buffer; 
     int strLen; 
     string username = "SYSTEM"; 
     if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WtsInfoClass.WTSUserName, out buffer, out strLen) && strLen > 1) 
     { 
      username = Marshal.PtrToStringAnsi(buffer); 
      WTSFreeMemory(buffer); 
      if (prependDomain) 
      { 
       if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WtsInfoClass.WTSDomainName, out buffer, out strLen) && strLen > 1) 
       { 
        username = Marshal.PtrToStringAnsi(buffer) + "\\" + username; 
        WTSFreeMemory(buffer); 
       } 
      } 
     } 
     return username; 
    } 

隨着你的類上面的代碼,你可以簡單地通過調用

string username = GetUsername(changeDescription.SessionId);