I hace a WPF application and I'm am using the following to obtain the OS details of my PC:
using (ManagementObjectSearcher win32OperatingSystem = new ManagementObjectSearcher("select * from Win32_OperatingSystem"))
{
foreach (ManagementObject obj in win32OperatingSystem.Get())
{
_operatingSystem = obj["Caption"].ToString();
_osArchitecture = obj["OSArchitecture"].ToString();
break;
}
}
WhenI step into this line:
ManagementObject obj in win32OperatingSystem.Get())
I get the following exception:
Invalid Query.
WHat is wrong here??
WMI classes have a namespace, you didn't specify one. Use WMI Code Creator to get your queries correct, it generates the C# code for you and you can run it right from the tool to check the results.
I would suggest using the properties of the Environment and OperatingSystem class (instead of ManagementObjectSearcher) to get those details.
string _operatingSystem = Environment.OSVersion.VersionString;
Related
I want to get all a list of all installed drivers on my machine. For this purpose I use WMI. But for unknown reason all properties returned have empty values (except for deviceID, DriverVersion and Signer) .
What I tried and considered so far:
running with and without admin rights makes no difference
no methods found like fetch, load, reload on any of involved objects found
no option found like lazyload
pnputil.exe and driversearch.exe do return data of all drivers, but the outputs of those a very hard to interpret
This is the C#-code:
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPSignedDriver"))
{
foreach (ManagementBaseObject u in searcher.Get())
{
foreach(PropertyData prop in u.Properties)
{
System.Console.WriteLine($"{prop.Name}={prop.Value}");
}
System.Console.WriteLine("===");
}
}
Output for first driver found:
Caption=
ClassGuid=
CompatID=
CreationClassName=
Description=
DeviceClass=
DeviceID=\\SVWPSW46\P3115 X WC 7120-D C S U A3
DeviceName=
DevLoader=
DriverDate=
DriverName=
DriverProviderName=
DriverVersion=2:6.0,2:5.2,2:5.1,2:5.0
FriendlyName=
HardWareID=
InfName=
InstallDate=
IsSigned=True
Location=
Manufacturer=
Name=
PDO=
Signer=Microsoft Windows
Started=
StartMode=
Status=
SystemCreationClassName=
SystemName=
===
...
I know we can get the BIOS information using system.management assembly but the assembly is not accessible for windows 8 app. I specifically need to know the serial number of the laptop on which the app is running. Is there any way that I can access that ?
I don't think there is a way if you are developing a Windows Modern UI App.
Modern UI Apps get run in a sandbox environment which have very limited access to anything. Check MSDN documentations on that.
If you are developing a desktop Windows app on the other hand, then try the following code:
(You need to import System.Management.dll into your project.)
using System;
using System.IO;
using System.Management;
namespace GetHardwareIds
{
internal class Program
{
private static void Main(string[] args)
{
using (StreamWriter writer = new StreamWriter(#"C:\HardwareInfo.txt"))
{
using
(
ManagementObjectSearcher searcher =
// Where __Superclass Is Null: selects only top-level classes.
// remove it if you need a list of all classes
// new ManagementObjectSearcher("Select * From meta_class Where __Superclass Is Null")
// this query only select the processor info. for more options uncomment top line
new ManagementObjectSearcher("Select * From meta_class Where __Class = 'Win32_Processor'")
)
{
foreach (ManagementObject managementObject in searcher.Get())
{
Console.WriteLine(managementObject.Path.ClassName);
writer.WriteLine(managementObject.Path.ClassName);
GetManagementClassProperties(managementObject.Path.ClassName, writer);
managementObject.Dispose();
}
}
}
}
public static void GetManagementClassProperties(string path, StreamWriter writer)
{
using (ManagementClass managementClass = new ManagementClass(path))
{
foreach (ManagementObject instance in managementClass.GetInstances())
{
foreach (PropertyData property in instance.Properties)
{
Console.WriteLine(" {0} = {1}", property.Name, property.Value);
writer.WriteLine(" {0} = {1}", property.Name, property.Value);
}
instance.Dispose();
}
}
}
}
}
Check this code. I am not a 100% clear on what you are trying to achieve but this code should return the device ID specified by Win8 (this code includes a concatenation of all ids.)
// get hardware token
HardwareToken token = HardwareIdentification.GetPackageSpecificToken(null);
// get hardware ID bytes
byte[] idBytes = hwToken.Id.ToArray();
// populate device ID as a string value
string deviceID = string.Join(",", idBytes);
Here is the link to MSDN articles about it:
http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.profile.hardwareidentification.getpackagespecifictoken.aspxThere is an entry for BIOS in the return structure based on these articles.
Hopefully, this does what you need. Let me know if it worked :)
Unfortunately the information you want to obtain is not available to WinRT applications.
Is there a .NET (C#) method or API call that I can use to query if a Windows Service is disabled? The relevant MSDN article is here.
I want to avoid querying the registry directly. Below is some of the code that I am using right now (and it works). However I am looking for something more elegant and less invasive.
const String basepathStr = #"System\CurrentControlSet\services\";
String subKeyStr = basepathStr + servicenameStr;
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subKeyStr))
{
return (int) key.GetValue("Start");
}
I did find a simliar question but I was hoping for a better answer since the answers are presumably outdated (3 years have passed).
This the most relevant section of the code I decided to use...thanks for the help all!
StartupState state = StartupState.Unknown;
try
{
PermissionSet fullTrust = new PermissionSet(System.Security.Permissions.PermissionState.Unrestricted);
fullTrust.Demand();
string wmiQuery = #"SELECT * FROM Win32_Service WHERE Name='" + servicenameStr + #"'";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
ManagementObjectCollection results = searcher.Get();
foreach (ManagementObject service in results)
{
if (service["StartMode"].ToString() == "Disabled")
state = StartupState.Disabled;
else
state = StartupState.Enabled;
}
return state;
}
catch (SecurityException se)
{
return StartupState.Refused;
}
catch (Exception e)
{
return StartupState.Error;
}
Use the ServiceController class to get information about services.
EDIT
Seems one of the things you can't do with the ServiceController is get the startup type. Googling showed the following blog post that has code that uses P/Invoke to get the service startup type: http://peterkellyonline.blogspot.de/2011/04/configuring-windows-service.html
Add a ref to System.Management and the following code will get you the StartMode
string wmiQuery = "SELECT * FROM Win32_Service WHERE Name='YourServiceName'";
var searcher = new ManagementObjectSearcher(wmiQuery);
var results = searcher.Get();
foreach (ManagementObject service in results)
{
Console.WriteLine(service["StartMode"]);
}
ServiceController class doesn't provide this information. You should use WMI. See here for detailed solution
WMI can be another way for querying the status of the windows services
You can use:
using System.ServiceProcess;
And then link the service you want to view the satus by:
// Link by service name
ServiceController TheServiceName = new ServiceController();
TheServiceName.ServiceName = "Spooler";
// Link by display name
ServiceController TheDisplayName = new ServiceController();
TheDisplayName.ServiceName = "Print Spooler";
To check for example the isRunning Status :
if (TheServiceName.Status == ServiceControllerStatus.Running)
MessageBox.Show("The service is running.");
Some of our customers inform us that in some cases following error appears:
System.Management.ManagementException: Błąd dostawcy.
at
System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus
errorCode)
at
System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
The error is generated while trying to loop through a colection returned by Get() method of the System.Mamangment.ManagementObjectSearcher object.
This is the code of my method:
private bool PrinterExists(string printerName)
{
bool retVal = false;
SelectQuery q = new SelectQuery("select caption from win32_printer");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(q))
{
foreach (ManagementObject printer in searcher.Get())
{
if(printer["Caption"].ToString() == printerName)
{
retVal = true;
break;
}
}
}
return retVal;
}
It seems that the problem appears only on Windows XP. The only workaround I know is reconstruction of WMI database. It sometimes helps, but unfortunatelly not always.
Can anyone tell me what is the reason of this error and how can I fix it?
There a many possible reasons you could get an error while enumerating a WMI collection, including that you don't have permissions to look at some properties of an object. You can check the permissions possibility by running the app as administrator and seeing if the error goes away.
Regardless of the underlying root cause, one solution you could try is to modify your WQL query to include the name of the printer you're looking for. By having WMI do the enumeration instead of you, it might bypass the problematic items.
SelectQuery q = new SelectQuery(
"select caption from win32_printer where Caption='Fax' ");
bool found = new System.Management.ManagementObjectSearcher(q).Get().Count > 0;
If that doesn't work, then put your comparison of Caption into an exception handler, and ignore printers that throw exceptions.
Of course, if the underlying problem is that you're trying to find printers that you don't have permissions to look at, then you'll need to adjust your application so that it's running with elevated permissions.
Hello I've got a bit of a problem. I'm trying to use WMI to list information about disks. When I run the code from the WMI code creator everything returns fine and I get the information I'm looking for. When I run the code from the application I'm writing I get an invalid class error that gets thrown from the foreach loop.
The code I wrote and WMI generated is essentially the same, only the output is different. What could I possibly be doing wrong. Here is the code I wrote.
public List<diskData> getDiskInfo()
{
List<diskData> dData = new List<diskData>();
diskData mydisk = null;
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM W32_LogicalDisk");
foreach (ManagementObject item in searcher.Get())
{
mydisk.name = Convert.ToString(item["Name"]);
}
return dData;
}
catch (Exception ex)
{
Console.WriteLine("This is the Message: " + ex.Message);
return dData;
}
}
Thanks for any help you guys can provide.
Paul
The Win32_LogicalDisk class name in your WMI query is misspelled as W32_LogicalDisk.