Get list of Windows users - c#

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.

Related

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"]);
}

How to get logged in user from a service in windows 8

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.

how many times software has been installed and uninstalled on a computer

Is there any way (in C#, using WMI classes) to find out that how many times a particular software has been installed and uninstalled?
I want to run it on remote computer. I am getting software list by following code:
ManagementScope scope = new ManagementScope(#"\\" + ipAddress + #"\root\cimv2");
ObjectQuery query = new ObjectQuery("Select * from Win32_Product");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
Console.Write(m["Caption"]+"\t");
Console.WriteLine(m["installDate"]);
}
Normally not.
When a program will be uninstalled every bit of the program should be removed from the machine like it was never their. Unfortunately nearly every program doesn't make a perfect job at this point leaving some artifacts on the machine.
Nevertheless the desired behavior is that after a uninstall everything is gone (including some kind of counter) so that it is only possible to check if a program is currently installed or not.
On the other site nothing permits a program to save somewhere some counter (e.g. registry) which will increased everytime a installation is started, but that's something specific for each program and no common mechanism exists where this counter should reside.

C# code to find all office updates installed

In add or remove programs you can view list of updates/patches for MS office Outlook. Is there a way to get this information using c# code. We tried WMI code
const string query = "SELECT HotFixID FROM Win32_QuickFixEngineering";
var search = new ManagementObjectSearcher(query);
var collection = search.Get();
foreach (ManagementObject quickFix in collection)
Console.WriteLine(quickFix["HotFixID"].ToString());
This only lists windows updates. Is there a way to list updates for office components?(for windows XP)
I believe you will have to use the registry to get these. The following registry keys should help:
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
You will have to loop though both the values for the HKLM and HKCU hives in order to be sure you have everything. Then you can filter on DisplayName and Publisher for each entry in order to get only the MS office patches.
Note you could also try to query the Win32_Product class to get products installed by the Windows installer. Although I have often found that it does not list everything you need (however it might be sufficient for your current problem - but I am not in a position to check right now).

Categories

Resources