Getting detail System Information without a DLLImport in dotNet
The two functions below can make getting information trivial because it writes the information out into clean XML which may be examined by XPath or LINQ.
- The first function calls the second using a built in list of the WMI objects (this can take a long time to run and will produce a huge file: BE WARNED -- run it once to see what is available.)
- The second function writes a short list specified in a string array (for example: use a text file with one item per line). This is likely the most common use.
- If you are planning to write to a file, you may find encoding issues.
using System; using System.Collections.Generic; using System.Management; using System.Text; using System.IO; using System.Xml;
Everything in the Wmi
The following obtains the list of available objects (some 1200+ on my Windows 7 box) and then gets information about each
/// <summary> /// Enumerates all of the WMI classes on the local machine /// </summary> /// <returns>Array of WMI providers available</returns> public static string[] AvailableWmiClasses() { var queue =new Queue<string>(); ManagementObjectSearcher searcher = new ManagementObjectSearcher( new ManagementScope("root\\cimv2"), new WqlObjectQuery("select * from meta_class"), null); foreach (ManagementClass wmiClass in searcher.Get()) { queue.Enqueue(wmiClass["__CLASS"].ToString()); } return queue.ToArray(); } /// <summary> /// Get information about all WMI providers installed locally /// </summary> /// <returns>String containing information formatted as XML</returns> public static String GetFullWmi() { return GetWmi(AvailableWmiClasses()); }
The Core Routine
public static string GetWmi(string[] wmiObjects) { StringWriter stringWriter = new StringWriter(); XmlTextWriter twriter = new XmlTextWriter(stringWriter); twriter.Formatting = Formatting.Indented; twriter.WriteStartDocument(); twriter.WriteStartElement("wmiinformation"); twriter.WriteAttributeString("start", DateTime.Now.ToString("s")); foreach (var wmiObject in wmiObjects) try { // next line may fail so we wrte Start Element only if it succeeds DateTime start = DateTime.Now; ManagementObjectSearcher searcher = new ManagementObjectSearcher(String.Format("SELECT * FROM {0}", wmiObject)); DateTime endquery = DateTime.Now; twriter.WriteStartElement(wmiObject); TimeSpan elapse = endquery - start; twriter.WriteAttributeString("queryMsec", elapse.TotalMilliseconds.ToString()); foreach (ManagementObject wmi in searcher.Get()) { twriter.WriteStartElement("item"); foreach (var prop in wmi.Properties) { if (prop.Value != null) { twriter.WriteStartElement("property"); switch (prop.Value.GetType().Name) { case "Boolean": twriter.WriteAttributeString(prop.Name, (bool)prop.Value ? "true" : "false"); break; case "String": twriter.WriteAttributeString(prop.Name, (string)prop.Value); break; case "UInt64": twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; case "UInt32": twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; case "UInt16": twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; case "Int64": twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; case "Int32": twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; case "Int16": twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; case "Double": twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; case "Byte": twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; case "UInt16[]": foreach (var x in (UInt16[])prop.Value) { twriter.WriteElementString("item", x.ToString()); } break; case "String[]": foreach (var x in (String[])prop.Value) { twriter.WriteElementString("item", x.ToString()); } break; case "Byte[]": foreach (var x in (Byte[])prop.Value) { twriter.WriteElementString("item", x.ToString()); } break; default: twriter.WriteAttributeString(prop.Name, prop.Value.ToString()); break; } twriter.WriteEndElement(); } } twriter.WriteEndElement(); } twriter.WriteEndElement(); } catch (Exception exc) { twriter.WriteElementString("Error", exc.Message); twriter.WriteEndElement(); // Close the WmiObject Tag } twriter.WriteEndElement(); twriter.WriteEndDocument(); twriter.Close(); return stringWriter.ToString(); }
Writing to a file with appropriate encoding
using (var output = new StreamWriter("systeminformation.xml",false,Encoding.Unicode)) { output.Write(wmiList == null ? GetFullWmi() : GetWmi(wmiList)); }
Comments
Post a Comment