Why "root\\StandardCimv2" in Windows 7 doesn't work? - c#

workWhen i try show list with adapters name in combobox like this:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\StandardCimv2","SELECT * FROM MSFT_NetAdapter");
foreach (ManagementObject queryObj in searcher.Get())
{
try
{
comboBox1.Items.Add(queryObj["Name"].ToString());
}
catch (Exception)
{
comboBox1.Items.Add("");
}
}
All good...because used Windows 8. If i run app on PC with Windows 7 i get error:
System.Management.ManagementException: Invalid namespace
Later I noticed one thing...if this line code:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\StandardCimv2","SELECT * FROM MSFT_NetAdapter")
Replace on this:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_NetworkAdapter");
The error disappears and everything works. And now Question!
Why this "root\StandardCimv2" not work in Win7? But with this "root\CIMV2" all good.
Thanks in advance.

The Win32_NetworkAdapter class works on Vista and 7.
This answer has an example of using it (in PowerShell) to retrieve Name and connection Speed:
https://stackoverflow.com/a/3002568/550712
It looks like it also has the "Name" property so it might work as a direct replacement in your code.

Related

C# ManagementException: Provider load failure when accessing MSFT_NetConnectionProfile

I have a problem with getting MSFT_NetConnectionProfile. I am able to access MSFT_NetAdapter and Win32_NetworkAdapter but I need informations from profile.
When I try to get it via PowerShell then there is no problem. Using a command found here on SO.
Get-WmiObject -Namespace root/StandardCimv2 -Class MSFT_NetConnectionProfile | Format-Table InterfaceAlias, Name
WBEMTest loads everything without error. I found WBEMTest here on SO
My C# code is:
using System.Management;
ManagementScope scope = new ManagementScope("ROOT\\StandardCimv2");
ObjectQuery query = new ObjectQuery("SELECT * FROM MSFT_NetConnectionProfile");
ManagementObjectSearcher networkAdapterSearcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection objectCollection = networkAdapterSearcher.Get();
try
{
foreach (ManagementObject item in objectCollection)
{
Console.WriteLine(item["Name"]);
Console.WriteLine(item["InterfaceAlias"]);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
I found that it works on my main development PC, but I need it to run on our embedded PC. The code sample is builded with .NET6 as single file application with .NET included (not installed on destination PC) so I suppose all DLLs should be linked.
Where should I look for the problem?

Unable to get system hard drive SerialNumber using Win32_DiskDrive

I'm using the following code to get my drive serial number. It's working fine with Windows 7, 8, 8.1, and 10 Professional, but I'm getting an error on Windows 10 Home.
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject wmi_HD in searcher.Get())
{
if (wmi_HD["SerialNumber"] == null)
hddId = null;
else
hddId = wmi_HD["SerialNumber"].ToString();
}
I'm getting
System.NullReferenceException : Object reference not set to an instance of an object.
Does anyone know why? What do I need to do to get the serial number in this case?
One more question: if I boot the OS from my pendrive, will this code work? How could I know that the OS is running from a pendrive or disk or any other resource?
When I go to the Device Manager, I see this:
I am adding this as an answer because it can save lot of time while debugging scenarios like System.NullReferenceException in WMI.
Windows+R (run command)
Type wbemtest
And connect to the machine for which you want to fetch information. Fire the query for Win32_DiskDrive and check the output for properties that you can fetch.
This is what I'm using on Windows 10 v1809:
using System;
using System.Management;
namespace GetSerialNo
{
class Program
{
static void Main(string[] args)
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject info in searcher.Get())
{
Console.WriteLine("DeviceID: " + info["DeviceID"].ToString());
Console.WriteLine("Model: " + "Model: " + info["Model"].ToString());
Console.WriteLine("Interface: " + "Interface: " + info["InterfaceType"].ToString());
Console.WriteLine("Serial#: " + "Serial#: " + info["SerialNumber"].ToString());
}
Console.ReadLine();
}
}
}
For details please see http://csharphelper.com/blog/2017/10/get-hard-drive-serial-number-c/
For the associated link Get Hard disk serial Number given by #ADreNaLiNe-DJ I wasn't able to find the required assembly reference for HardDrive hd = new HardDrive();

How do I get the currently-logged username from a Windows service in .NET?

I have a Windows service which needs the currently logged username. I tried System.Environment.UserName, Windows identity and Windows form authentication, but all are returning "System" as the user my service is running as has system privileges. Is there a way to get the currently logged in username without changing my service account type?
This is a WMI query to get the user name:
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];
You will need to add System.Management under References manually.
If you are in a network of users, then the username will be different:
Environment.UserName
Will Display format : 'Username',
rather than
System.Security.Principal.WindowsIdentity.GetCurrent().Name
Will Display format : 'NetworkName\Username'
Choose the format you want.
ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem") solution worked fine for me. BUT it does not work if the service is started over a Remote Desktop Connection.
To work around this, we can ask for the username of the owner of an interactive process that always is running on a PC: explorer.exe. This way, we always get the currently Windows logged-in username from our Windows service:
foreach (System.Management.ManagementObject Process in Processes.Get())
{
if (Process["ExecutablePath"] != null &&
System.IO.Path.GetFileName(Process["ExecutablePath"].ToString()).ToLower() == "explorer.exe" )
{
string[] OwnerInfo = new string[2];
Process.InvokeMethod("GetOwner", (object[])OwnerInfo);
Console.WriteLine(string.Format("Windows Logged-in Interactive UserName={0}", OwnerInfo[0]));
break;
}
}
Modified code of Tapas's answer:
Dim searcher As New ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem")
Dim collection As ManagementObjectCollection = searcher.[Get]()
Dim username As String
For Each oReturn As ManagementObject In collection
username = oReturn("UserName")
Next
Just in case someone is looking for user Display Name as opposed to User Name, like me.
Here's the treat :
System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName.
Add Reference to System.DirectoryServices.AccountManagement in your project.
Try WindowsIdentity.GetCurrent(). You need to add reference to System.Security.Principal
You can also try
System.Environment.GetEnvironmentVariable("UserName");
Completing the answer from #xanblax
private static string getUserName()
{
SelectQuery query = new SelectQuery(#"Select * from Win32_Process");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
foreach (System.Management.ManagementObject Process in searcher.Get())
{
if (Process["ExecutablePath"] != null && string.Equals(Path.GetFileName(Process["ExecutablePath"].ToString()), "explorer.exe", StringComparison.OrdinalIgnoreCase))
{
string[] OwnerInfo = new string[2];
Process.InvokeMethod("GetOwner", (object[])OwnerInfo);
return OwnerInfo[0];
}
}
}
return "";
}

Check anti-virus status in C#

I need to check a group of servers to see whether the anti virus is up-to-date and running. Tricky thing is that they are spread over Windows 2003 and 2008 servers and I need to be able to check them all.
Is there any way of doing this with C# or VB.NET?
I have briefly looked around using WMI, but it appears on 2008/win7 computers Microsoft has changed what information they give back to you.
In summary, I need the following:
AV name
AV version
AV Up-to-Date
AV Enabled/Running
Can anyone help?
Sample can be found here using WMI as you mentioned. The poster states this is being done on a Win 7 machine; so the code below should get you started...
ConnectionOptions _connectionOptions = new ConnectionOptions();
//Not required while checking it in local machine.
//For remote machines you need to provide the credentials
//options.Username = "";
//options.Password = "";
_connectionOptions.EnablePrivileges = true;
_connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
//Connecting to SecurityCenter2 node for querying security details
ManagementScope _managementScope = new ManagementScope(string.Format("\\\\{0}\\root\\SecurityCenter2", ipAddress), _connectionOptions);
_managementScope.Connect();
//Querying
ObjectQuery _objectQuery = new ObjectQuery("SELECT * FROM AntivirusProduct");
ManagementObjectSearcher _managementObjectSearcher =
new ManagementObjectSearcher(_managementScope, _objectQuery);
ManagementObjectCollection _managementObjectCollection = _managementObjectSearcher.Get();
if (_managementObjectCollection.Count > 0)
{
foreach (ManagementObject item in _managementObjectCollection)
{
Console.WriteLine(item["displayName"]);
//For Kaspersky AntiVirus, I am getting a null reference here.
//Console.WriteLine(item["productUptoDate"]);
//If the value of ProductState is 266240 or 262144, its an updated one.
Console.WriteLine(item["productState"]);
}
}
Depending on how your environment is setup you may need to specify your security and permissions. You should also note that some antivirus products (like McAfee) do not make data available through WMI.
You can query the Antivirus information from WMI using this snippet:
string computer = Environment.MachineName;
string wmipath = #"\\" + computer + #"\root\SecurityCenter";
string query = #"SELECT * FROM AntivirusProduct";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmipath, query);
ManagementObjectCollection results = searcher.Get();
foreach (ManagementObject result in results)
{
// do something with `result[value]`);
}

Get PC's Monitor Information Using .NET / WMI

Is there anyway using WMI/.Net to grab monitor information such as Manufacturer, Serial Number, Monitor Size etc.?
Using a script is an option as well, or can I query the registry directly to get this information?
SELECT * FROM Win32_DesktopMonitor doesn't really return any useful information for me in this case.
Hey, I use this tool for a lot of my WMI work, especially when prototyping and creating POCs....
Microsoft WMI Code Generator
This tool is great for creating quick console app code for any wmi query or method invocation in both C# and VB.NET
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_DesktopMonitor");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_DesktopMonitor instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("Description: {0}", queryObj["Description"]);
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
The code above will get you the make and model of the monitor.
You may want to try this
https://raw.githubusercontent.com/MaxAnderson95/Get-Monitor-Information/master/Get-Monitor.ps1
Cheers
That select query should give you what you want. Here is the documentation which contains the details of the query.
Then you could do something like this:
public void GetMonitorDetails()
{
using(ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor")
{
foreach(ManagementObject currentObj in searcher.Get())
{
String name = currentObj("Name").ToString();
String device_id = currentObj("DeviceID").ToString();
// ...
}
}
}
This post, combined with the answer below about the WMI management tool had my answer. Here is the code that returns your monitor resolutions.
try {
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM WmiMonitorBasicDisplayParams");
foreach (ManagementObject queryObj in searcher.Get()) {
Debug.WriteLine("-----------------------------------");
Debug.WriteLine("WmiMonitorBasicDisplayParams instance");
Debug.WriteLine("-----------------------------------");
Debug.WriteLine("Description: {0}", queryObj["SupportedDisplayFeatures"]);
}
} catch (ManagementException e) {
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
In my case, I'm still stuck, because it is returning the "scaled down" resolution of each monitor. One of mine is a 4K display, being reported as 2560x1440.

Categories

Resources