How to get logged in user from a service in windows 8 - c#

I am developing a C# windows service.
I need to know (from the service) who is the currently logged on user.
I tried to follow the answer in here with this code:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];
But the problem is that it works only on Windows 7, but on Windows 8 I get an empty string.
Was the WMI changed in Windows 8?

The problem wasn't with windows 8 but the fact that I used remote connection.
This WMI doesn't work for remote connection.

Related

How to get logged in user in windows server using C# when "Application owner" is admin and not a logged in user? [duplicate]

This question already has answers here:
How to get current windows username from windows service in multiuser environment using .NET
(6 answers)
Closed 1 year ago.
I am writing an application that will run on windows server.
The scenario is that user will login using normal domain account and application will run using administrator account.
I need to get the user currently logged in to windows to do some processing.
when I get user name using following method it gives me the admin account used to run the exe and not the account logged in to windows current session.
string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Then I tried following method to get the logged in user
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];
This code is working fine on windows 10 and giving me the user currently logged in to windows. But on windows server 2012 it is returning empty string.
How can I get the logged in user when running the exe on windows server??
I dont want to know how many sessions are running on windows server. i want to know the current logged in user.
In Windows, current logged-on user is written to environment variable USERNAME, his domain - to USERDOMAIN, and you can read this values with System.Environment.GetEnvironmentVariable()
You can list all (currently set) environment variables with set command in console/command prompt.

Not able to use ManagementObjectSearcher under Windows Service (Topshelf)

I have simple Windows Service (Topshelf) written in .NET. When I try to use ManagementObjectSearcher (specifically to search connected disk drives) I get error:
The specified service does not exist as an installed service. (Exception from HRESULT: 0x80070424)
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
searcher.Get())
Everything else works fine (eg. using repository to access DB), only fails on this.

Get list of Windows users

I have the following instructions in my code.
ManagementObjectSearcher usersSearcher = new ManagementObjectSearcher(#"SELECT * FROM Win32_UserAccount");
ManagementObjectCollection users = usersSearcher.Get();
It works fine on most machines. But in some cases the result (users) is empty. I failed to determine the reason. all three machine where it had happened are Windows 7 (Ultimate, Professional, Home Basic).
Is there any special conditions that causes this query to fail?
Thanks in advance.

Environment.OSVersion sometimes reporting Windows 8 for 8.1, although manifest is set correctly

Since Environment.OSVersion may lie about whether Win 8 or 8.1 is running, we declared in our manifest specifically that we target Windows 8.1 in our application.
However, Environment.OSVersion.Minor seems to be unreliable in returning the version. We wrapped it in one of our libraries, but on some of our dev machines, it returns "2" (Windows 8), on other "3" (Windows 8.1). There aren't any specific compatibility settings applied (as far as we know), but we can't seem to track the issue down.
Are there other options to get the Windows version via .Net, without using the Win32 API functions mentioned at MSDN?
Allright, I did it with WMI as #mike-z suggested:
SelectQuery query = new SelectQuery(#"Select * from Win32_OperatingSystem");
string wmiVersion = String.Empty;
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
foreach (var process in searcher.Get())
{
wmiVersion = process["Version"].ToString().Substring(0, 3);
}
}
switch (wmiVersion)
{
case "6.3": return "Windows 8.1";
// ...
}
Disclaimer: this is meant as a "when everything else fails..." kind of answer
You could parse the output of VER and see if it's accurate.
On my box (8.1 Pro) I see this
C:> ver
Microsoft Windows [Version 6.3.9600]
C:>

Remotely determine interactive/active user on Windows 7 machine

Anyone else had to determine who the currently logged on user is remotely in a Windows 7 environment? I am using .NET 4.0 and C#. The environment is mixed XP and 7.
WMI queries involving sessions result in all active sessions, but not the session that is interactive.
UserName from ComputerSystem (WMI) returns null exception if user is connected via Remote Desktop, which is common enough that this method cannot be used.
PsLoggedOn takes too long for my purposes (yes, 300 ms is too long) and is surprisingly not accurate 100% of the time
Using p/invoke for WTSGetActiveConsoleSessionID or LsaEnumerateLogonSessions is too complicated and prone to memory leaks (from what I've read)
tasklist /S <computername> will return information for XP systems, but Windows 7 won't be agreeable thanks to that lovely UAC.
HKCU (win registry) is inaccessible remotely due to permissions restrictions, HKU is accessible, but Volatile Environment doesn't appear to have a tag for "active"
So far, the most reliable way is using PsExec to remotely execute qwinsta from the command line and traverse the output to text remotely. This is annoying and takes time (more than PsLoggedOn), but I'm running out of ideas here for reliability. Reliability before speed, but speed is very important in terms of cost benefit.
Third party tools are not an option, has to be a script, preferably WMI and C#. I delved into hitting the DC using Principal objects, but I'm afraid I might have confused myself more. Also, all user accounts are administrators.
I've done a lot of research over Google, but I am thinking that maybe I am looking in the wrong place.
Any takers?
you can achieve this by browsing Win32_ComputerSystem class's UserName Propperty :
ConnectionOptions con = new ConnectionOptions();
con.Username = "Administrator";
con.Password = "********";
ManagementScope scope = new ManagementScope(#"\\" + strIPAddress + #"\root\cimv2", con);
scope.Connect();
//check for scope.IsConnected, then process
ManagementObjectSearcher searcher =new ManagementObjectSearcher(#"\\" + strIPAddress + #"\root\cimv2", "SELECT * FROM Win32_ComputerSystem");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_ComputerSystem instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("UserName: {0}", queryObj["UserName"]);
}

Categories

Resources