Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Wmi / managed / System / Management / ManagementQuery.cs / 1305376 / ManagementQuery.cs
using System; using System.Collections.Specialized; using WbemUtilities_v1; using WbemClient_v1; using System.Globalization; using System.Reflection; using System.ComponentModel.Design.Serialization; using System.ComponentModel; using System.ComponentModel.Design; namespace System.Management { //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Provides an abstract base class for all management query objects. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// [TypeConverter(typeof(ManagementQueryConverter ))] public abstract class ManagementQuery : ICloneable { internal const string DEFAULTQUERYLANGUAGE = "WQL"; internal static readonly string tokenSelect = "select "; // Keep trailing space char. //Used when any public property on this object is changed, to signal //to the containing object that it needs to be refreshed. internal event IdentifierChangedEventHandler IdentifierChanged; //Fires IdentifierChanged event internal void FireIdentifierChanged() { if (IdentifierChanged != null) IdentifierChanged(this, null); } private string queryLanguage; private string queryString; internal void SetQueryString (string qString) { queryString = qString; } //default constructor internal ManagementQuery() : this(DEFAULTQUERYLANGUAGE, null) {} //parameterized constructors internal ManagementQuery(string query) : this(DEFAULTQUERYLANGUAGE, query) {} internal ManagementQuery(string language, string query) { QueryLanguage = language; QueryString = query; } ///This class is abstract; only /// derivatives of it are actually used in the API. ////// Parses the query string and sets the property values accordingly. /// /// The query string to be parsed. protected internal virtual void ParseQuery (string query) {} // //properties // ////// ///Gets or sets the query in text format. ////// public virtual string QueryString { get {return (null != queryString) ? queryString : String.Empty;} set { if (queryString != value) { ParseQuery (value); // this may throw queryString = value; FireIdentifierChanged (); } } } ///If the query object is /// constructed with no parameters, the property is null until specifically set. If the /// object was constructed with a specified query, the property returns the specified /// query string. ////// ///Gets or sets the query language used in the query /// string, defining the format of the query string. ////// public virtual String QueryLanguage { get {return (null != queryLanguage) ? queryLanguage : String.Empty;} set { if (queryLanguage != value) { queryLanguage = value; FireIdentifierChanged (); } } } //ICloneable ///Can be set to any supported query /// language. "WQL" is the only value supported intrinsically by WMI. ////// ///Returns a copy of the object. ////// The cloned object. /// public abstract object Clone(); internal static void ParseToken (ref string q, string token, string op, ref bool bTokenFound, ref string tokenValue) { if (bTokenFound) throw new ArgumentException (RC.GetString("INVALID_QUERY_DUP_TOKEN")); // Invalid query - duplicate token bTokenFound = true; q = q.Remove (0, token.Length).TrimStart (null); // Next character should be the operator if any if (op != null) { if (0 != q.IndexOf(op, StringComparison.Ordinal)) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query // Strip off the op and any leading WS q = q.Remove(0, op.Length).TrimStart(null); } if (0 == q.Length) throw new ArgumentException (RC.GetString("INVALID_QUERY_NULL_TOKEN")); // Invalid query - token has no value // Next token should be the token value - look for terminating WS // or end of string int i; if (-1 == (i = q.IndexOf (' '))) i = q.Length; // No WS => consume entire string tokenValue = q.Substring (0, i); q = q.Remove (0, tokenValue.Length).TrimStart(null); } internal static void ParseToken (ref string q, string token, ref bool bTokenFound) { if (bTokenFound) throw new ArgumentException (RC.GetString("INVALID_QUERY_DUP_TOKEN")); // Invalid query - duplicate token bTokenFound = true; q = q.Remove (0, token.Length).TrimStart (null); } }//ManagementQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a management query that returns instances or classes. ////// ///This class or its derivatives are used to specify a /// query in the ///. Use /// a more specific query class whenever possible. /// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class ObjectQuery : ManagementQuery { ///using System; /// using System.Management; /// /// // This sample demonstrates creating a query. /// /// class Sample_ObjectQuery /// { /// public static int Main(string[] args) /// { /// ObjectQuery objectQuery = new ObjectQuery("select * from Win32_Share"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(objectQuery); /// foreach (ManagementObject share in searcher.Get()) /// { /// Console.WriteLine("Share = " + share["Name"]); /// } /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates creating a query. /// /// Class Sample_ObjectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// Dim objectQuery As New ObjectQuery("select * from Win32_Share") /// Dim searcher As New ManagementObjectSearcher(objectQuery) /// Dim share As ManagementObject /// For Each share In searcher.Get() /// Console.WriteLine("Share = " & share("Name")) /// Next share /// Return 0 /// End Function /// End Class ///
////// ///Initializes a new instance of the ////// class. /// public ObjectQuery() : base() {} ///Initializes a new instance of the ////// class with no initialized values. This /// is the default constructor. /// /// The string representation of the query. public ObjectQuery(string query) : base(query) {} ///Initializes a new instance of the ////// class /// for a specific query string. /// /// The query language in which this query is specified. /// The string representation of the query. public ObjectQuery(string language, string query) : base(language, query) {} //ICloneable ///Initializes a new instance of the ////// class for a specific /// query string and language. /// ///Returns a copy of the object. ////// The cloned object. /// public override object Clone () { return new ObjectQuery(QueryLanguage, QueryString); } }//ObjectQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WMI event query. ////// ///Objects of this class or its derivatives are used in /// ///to subscribe to /// WMI events. Use more specific derivatives of this class whenever possible. /// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class EventQuery : ManagementQuery { ///using System; /// using System.Management; /// /// // This sample demonstrates how to subscribe to an event /// // using the EventQuery object. /// /// class Sample_EventQuery /// { /// public static int Main(string[] args) /// { /// //For this example, we make sure we have an arbitrary class on root\default /// ManagementClass newClass = new ManagementClass( /// "root\\default", /// String.Empty, /// null); /// newClass["__Class"] = "TestWql"; /// newClass.Put(); /// /// //Create a query object for watching for class deletion events /// EventQuery eventQuery = new EventQuery("select * from __classdeletionevent"); /// /// //Initialize an event watcher object with this query /// ManagementEventWatcher watcher = new ManagementEventWatcher( /// new ManagementScope("root/default"), /// eventQuery); /// /// //Set up a handler for incoming events /// MyHandler handler = new MyHandler(); /// watcher.EventArrived += new EventArrivedEventHandler(handler.Arrived); /// /// //Start watching for events /// watcher.Start(); /// /// //For this example, we delete the class to trigger an event /// newClass.Delete(); /// /// //Nothing better to do - we loop to wait for an event to arrive. /// while (!handler.IsArrived) { /// System.Threading.Thread.Sleep(1000); /// } /// /// //In this example we only want to wait for one event, so we can stop watching /// watcher.Stop(); /// /// //Get some values from the event. /// //Note: this can also be done in the event handler. /// ManagementBaseObject eventArg = /// (ManagementBaseObject)(handler.ReturnedArgs.NewEvent["TargetClass"]); /// Console.WriteLine("Class Deleted = " + eventArg["__CLASS"]); /// /// return 0; /// } /// /// public class MyHandler /// { /// private bool isArrived = false; /// private EventArrivedEventArgs args; /// /// //Handles the event when it arrives /// public void Arrived(object sender, EventArrivedEventArgs e) { /// args = e; /// isArrived = true; /// } /// /// //Public property to get at the event information stored in the handler /// public EventArrivedEventArgs ReturnedArgs { /// get { /// return args; /// } /// } /// /// //Used to determine whether the event has arrived or not. /// public bool IsArrived { /// get { /// return isArrived; /// } /// } /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates how to subscribe an event /// ' using the EventQuery object. /// /// Class Sample_EventQuery /// Public Shared Sub Main() /// /// 'For this example, we make sure we have an arbitrary class on root\default /// Dim newClass As New ManagementClass( _ /// "root\default", _ /// String.Empty, Nothing) /// newClass("__Class") = "TestWql" /// newClass.Put() /// /// 'Create a query object for watching for class deletion events /// Dim eventQuery As New EventQuery("select * from __classdeletionevent") /// /// 'Initialize an event watcher object with this query /// Dim watcher As New ManagementEventWatcher( _ /// New ManagementScope("root/default"), _ /// eventQuery) /// /// 'Set up a handler for incoming events /// Dim handler As New MyHandler() /// AddHandler watcher.EventArrived, AddressOf handler.Arrived /// /// 'Start watching for events /// watcher.Start() /// /// 'For this example, we delete the class to trigger an event /// newClass.Delete() /// /// 'Nothing better to do - we loop to wait for an event to arrive. /// While Not handler.IsArrived /// Console.Write("0") /// System.Threading.Thread.Sleep(1000) /// End While /// /// 'In this example we only want to wait for one event, so we can stop watching /// watcher.Stop() /// /// 'Get some values from the event /// 'Note: this can also be done in the event handler. /// Dim eventArg As ManagementBaseObject = CType( _ /// handler.ReturnedArgs.NewEvent("TargetClass"), _ /// ManagementBaseObject) /// Console.WriteLine(("Class Deleted = " + eventArg("__CLASS"))) /// /// End Sub /// /// Public Class MyHandler /// Private _isArrived As Boolean = False /// Private args As EventArrivedEventArgs /// /// 'Handles the event when it arrives /// Public Sub Arrived(sender As Object, e As EventArrivedEventArgs) /// args = e /// _isArrived = True /// End Sub /// /// 'Public property to get at the event information stored in the handler /// Public ReadOnly Property ReturnedArgs() As EventArrivedEventArgs /// Get /// Return args /// End Get /// End Property /// /// 'Used to determine whether the event has arrived or not. /// Public ReadOnly Property IsArrived() As Boolean /// Get /// Return _isArrived /// End Get /// End Property /// End Class /// End Class ///
////// ///Initializes a new instance of the ////// class. /// public EventQuery() : base() {} ///Initializes a new instance of the ////// class. This is the /// default constructor. /// /// A textual representation of the event query. public EventQuery(string query) : base(query) {} ///Initializes a new instance of the ////// class for the specified query. /// /// The language in which the query string is specified. /// The string representation of the query. public EventQuery(string language, string query) : base(language, query) {} //ICloneable ///Initializes a new instance of the ////// class for the specified /// language and query. /// ///Returns a copy of the object. ////// The cloned object. /// public override object Clone() { return new EventQuery(QueryLanguage, QueryString); } }//EventQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WMI data query in WQL format. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class WqlObjectQuery : ObjectQuery { //constructors //Here we don't take a language argument but hard-code it to WQL in the base class ///using System; /// using System.Management; /// /// // This sample demonstrates how to use a WqlObjectQuery class to /// // perform an object query. /// /// class Sample_WqlObjectQuery /// { /// public static int Main(string[] args) { /// WqlObjectQuery objectQuery = new WqlObjectQuery("select * from Win32_Share"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(objectQuery); /// /// foreach (ManagementObject share in searcher.Get()) { /// Console.WriteLine("Share = " + share["Name"]); /// } /// /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrate how to use a WqlObjectQuery class to /// ' perform an object query. /// /// Class Sample_WqlObjectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// Dim objectQuery As New WqlObjectQuery("select * from Win32_Share") /// Dim searcher As New ManagementObjectSearcher(objectQuery) /// /// Dim share As ManagementObject /// For Each share In searcher.Get() /// Console.WriteLine("Share = " & share("Name")) /// Next share /// /// Return 0 /// End Function /// End Class ///
////// ///Initializes a new instance of the ///class. /// public WqlObjectQuery() : base(null) {} ///Initializes a new instance of the ///class. This is the /// default constructor. /// ///Initializes a new instance of the ///class initialized to the /// specified query. The representation of the data query. public WqlObjectQuery(string query) : base(query) {} //QueryLanguage property is read-only in this class (does this work ??) ////// ///Gets or sets the language of the query. ////// public override string QueryLanguage { get {return base.QueryLanguage;} } //ICloneable ///The value of this /// property is always "WQL". ////// ///Creates a copy of the object. ////// The copied object. /// public override object Clone() { return new WqlObjectQuery(QueryString); } }//WqlObjectQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WQL SELECT data query. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class SelectQuery : WqlObjectQuery { private bool isSchemaQuery = false; private string className; private string condition; private StringCollection selectedProperties; //default constructor ///using System; /// using System.Management; /// /// // This sample demonstrates how to perform a WQL select query. /// /// class Sample_SelectQuery /// { /// public static int Main(string[] args) { /// SelectQuery selectQuery = new SelectQuery("win32_logicaldisk"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(selectQuery); /// /// foreach (ManagementObject disk in searcher.Get()) { /// Console.WriteLine(disk.ToString()); /// } /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates how to perform a WQL select query. /// /// Class Sample_SelectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// Dim selectQuery As New SelectQuery("win32_logicaldisk") /// Dim searcher As New ManagementObjectSearcher(selectQuery) /// /// Dim disk As ManagementObject /// For Each disk In searcher.Get() /// Console.WriteLine(disk.ToString()) /// Next disk /// /// Return 0 /// End Function /// End Class ///
////// ///Initializes a new instance of the ////// class. /// public SelectQuery() :this(null) {} //parameterized constructors //ISSUE : We have 2 possible constructors that take a single string : // one that takes the full query string and the other that takes the class name. // We resolve this by trying to parse the string, if it succeeds we assume it's the query, if // not we assume it's the class name. ///Initializes a new instance of the ////// class. This is the /// default constructor. /// /// The entire query or the class name to use in the query. The parser in this class attempts to parse the string as a valid WQL SELECT query. If the parser is unsuccessful, it assumes the string is a class name. ///Initializes a new instance of the ///class for the specified /// query or the specified class name. /// public SelectQuery(string queryOrClassName) { selectedProperties = new StringCollection (); if (null != queryOrClassName) { // Minimally determine if the string is a query or class name. // if (queryOrClassName.TrimStart().StartsWith(tokenSelect, StringComparison.OrdinalIgnoreCase)) { // Looks to be a query - do further checking. // QueryString = queryOrClassName; // Parse/validate; may throw. } else { // Do some basic sanity checking on whether it's a class name // ManagementPath p = new ManagementPath (queryOrClassName); if (p.IsClass && (p.NamespacePath.Length==0)) ClassName = queryOrClassName; else throw new ArgumentException (RC.GetString("INVALID_QUERY"),"queryOrClassName"); } } } ///SelectQuery s = new SelectQuery("SELECT * FROM Win32_Service WHERE State='Stopped'); /// /// or /// /// //This is equivalent to "SELECT * FROM Win32_Service" /// SelectQuery s = new SelectQuery("Win32_Service"); ///
///Dim s As New SelectQuery("SELECT * FROM Win32_Service WHERE State='Stopped') /// /// or /// /// //This is equivalent to "SELECT * FROM Win32_Service" /// Dim s As New SelectQuery("Win32_Service") ///
////// /// The name of the class to select in the query. /// The condition to be applied in the query. ///Initializes a new instance of the ////// class with the specified /// class name and condition. /// public SelectQuery(string className, string condition) : this(className, condition, null) {} ///SelectQuery s = new SelectQuery("Win32_Process", "HandleID=1234"); ///
///Dim s As New SelectQuery("Win32_Process", "HandleID=1234") ///
////// /// The name of the class from which to select. /// The condition to be applied to instances of the selected class. /// An array of property names to be returned in the query results. ///Initializes a new instance of the ////// class with the specified /// class name and condition, selecting only the specified properties. /// public SelectQuery(string className, string condition, string[] selectedProperties) : base () { this.isSchemaQuery = false; this.className = className; this.condition = condition; this.selectedProperties = new StringCollection (); if (null != selectedProperties) this.selectedProperties.AddRange (selectedProperties); BuildQuery(); } ///String[] properties = {"VariableName", "VariableValue"}; /// /// SelectQuery s = new SelectQuery("Win32_Environment", /// "User='<system>'", /// properties); ///
///Dim properties As String[] = {"VariableName", "VariableValue"} /// /// Dim s As New SelectQuery("Win32_Environment", _ /// "User=""<system>""", _ /// properties) ///
////// ///Initializes a new instance of the ////// class for a schema query, optionally specifying a condition. For schema queries, /// only the parameter is valid: /// and /// are not supported and are ignored. to indicate that this is a schema query; otherwise, . A value is invalid in this constructor. /// The condition to be applied to form the result set of classes. /// /// public SelectQuery(bool isSchemaQuery, string condition) : base () { if (isSchemaQuery == false) throw new ArgumentException(RC.GetString("INVALID_QUERY"), "isSchemaQuery"); this.isSchemaQuery = true; this.className = null; this.condition = condition; this.selectedProperties = null; BuildQuery(); } ///SelectQuery s = new SelectQuery(true, "__CLASS = 'Win32_Service'"); ///
///Dim s As New SelectQuery(true, "__CLASS = ""Win32_Service""") ///
////// ///Gets or sets the query in the ///, in string form. /// ///A string representing the query. ////// ///Setting this /// property value overrides any previous value stored in the object. In addition, setting this /// property causes the other members of the object to be updated when the string /// is reparsed. ////// public override string QueryString { get { // We need to force a rebuild as we may not have detected // a change to selected properties BuildQuery (); return base.QueryString;} set { base.QueryString = value; } } ///SelectQuery s = new SelectQuery(); /// s.QueryString = "SELECT * FROM Win32_LogicalDisk"; ///
///Dim s As New SelectQuery() /// s.QueryString = "SELECT * FROM Win32_LogicalDisk" ///
////// ///Gets or sets a value indicating whether this query is a schema query or an instances query. ////// ////// if this query /// should be evaluated over the schema; if the query should /// be evaluated over instances. /// public bool IsSchemaQuery { get { return isSchemaQuery; } set { isSchemaQuery = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new query type. ////// ///Gets or sets the class name to be selected from in the query. ////// ///A string representing the name of the /// class. ////// ///Setting this property value /// overrides any previous value stored in the object. The query string is /// rebuilt to reflect the new class name. ////// public string ClassName { get { return (null != className) ? className : String.Empty; } set { className = value; BuildQuery(); FireIdentifierChanged(); } } ///SelectQuery s = new SelectQuery("SELECT * FROM Win32_LogicalDisk"); /// Console.WriteLine(s.QueryString); //output is : SELECT * FROM Win32_LogicalDisk /// /// s.ClassName = "Win32_Process"; /// Console.WriteLine(s.QueryString); //output is : SELECT * FROM Win32_Process ///
///Dim s As New SelectQuery("SELECT * FROM Win32_LogicalDisk") /// Console.WriteLine(s.QueryString) 'output is : SELECT * FROM Win32_LogicalDisk /// /// s.ClassName = "Win32_Process" /// Console.WriteLine(s.QueryString) 'output is : SELECT * FROM Win32_Process ///
////// ///Gets or sets the condition to be applied in the SELECT /// query. ////// A string containing the condition to /// be applied in the SELECT query. /// ////// public string Condition { get { return (null != condition) ? condition : String.Empty; } set { condition = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any previous value /// stored in the object. The query string is rebuilt to reflect the new /// condition. ////// ///Gets or sets an array of property names to be /// selected in the query. ////// ///A ///containing the names of the /// properties to be selected in the query. /// public StringCollection SelectedProperties { get { return selectedProperties; } set { if (null != value) { // A tad painful since StringCollection doesn't support ICloneable StringCollection src = (StringCollection)value; StringCollection dst = new StringCollection (); foreach (String s in src) dst.Add (s); selectedProperties = dst; } else selectedProperties = new StringCollection (); BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any previous value stored /// in the object. The query string is rebuilt to reflect the new /// properties. ////// Builds the query string according to the current property values. /// protected internal void BuildQuery() { string s; if (isSchemaQuery == false) //this is an instances query { //If the class name is not set we can't build a query //Shouldn't throw here because the user may be in the process of filling in the properties... if (className == null) SetQueryString (String.Empty); if ((className == null) || (className.Length==0)) return; //Select clause s = tokenSelect; //If properties are specified list them if ((null != selectedProperties) && (0 < selectedProperties.Count)) { int count = selectedProperties.Count; for (int i = 0; i < count; i++) s = s + selectedProperties[i] + ((i == (count - 1)) ? " " : ","); } else s = s + "* "; //From clause s = s + "from " + className; } else //this is a schema query, ignore className or selectedProperties. { //Select clause s = "select * from meta_class"; } //Where clause if ((Condition != null) && (Condition.Length != 0)) s = s + " where " + condition; //Set the queryString member to the built query (NB: note we set //by accessing the internal helper function rather than the property, //since we do not want to force a parse of a query we just built). SetQueryString (s); } ////// Parses the query string and sets the property values accordingly. /// /// The query string to be parsed. protected internal override void ParseQuery(string query) { //Clear out previous property values className = null; condition = null; if (selectedProperties != null) selectedProperties.Clear(); //Trim whitespaces string q = query.Trim(); bool bFound = false; string tempProp; int i; if (isSchemaQuery == false) //instances query { //Find "select" clause and get the property list if exists string keyword = tokenSelect; if ((q.Length >= keyword.Length) && (String.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase) == 0)) //select clause found { ParseToken (ref q, keyword, ref bFound); if (q[0] != '*') //we have properties { if (null != selectedProperties) selectedProperties.Clear (); else selectedProperties = new StringCollection (); //get the property list while (true) { if ((i = q.IndexOf(',')) > 0) { tempProp = q.Substring(0, i); q = q.Remove(0, i+1).TrimStart(null); tempProp = tempProp.Trim(); if (tempProp.Length>0) selectedProperties.Add(tempProp); } else { //last property in the list if ((i = q.IndexOf(' ')) > 0) { tempProp = q.Substring(0, i); q = q.Remove(0, i).TrimStart(null); selectedProperties.Add(tempProp); break; } else //bad query throw new ArgumentException(RC.GetString("INVALID_QUERY")); } } //while } else q = q.Remove(0, 1).TrimStart(null); } else //select clause has to be there, otherwise the parsing fails throw new ArgumentException(RC.GetString("INVALID_QUERY")); //Find "from" clause, get the class name and remove the clause keyword = "from "; bFound = false; if ((q.Length >= keyword.Length) && (String.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase) == 0)) //from clause found ParseToken(ref q, keyword, null, ref bFound, ref className); else //from clause has to be there, otherwise the parsing fails throw new ArgumentException(RC.GetString("INVALID_QUERY")); //Find "where" clause, get the condition out and remove the clause keyword = "where "; if ((q.Length >= keyword.Length) && (String.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase) == 0)) //where clause exists { condition = q.Substring(keyword.Length).Trim(); } } //if isSchemaQuery == false else //this is a schema query { //Find "select" clause and make sure it's the right syntax string keyword = "select"; // Should start with "select" if ((q.Length < keyword.Length) || (0 != String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"select"); q = q.Remove (0, keyword.Length).TrimStart (null); // Next should be a '*' if (0 != q.IndexOf ('*', 0)) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"*"); q = q.Remove (0, 1).TrimStart (null); // Next should be "from" keyword = "from"; if ((q.Length < keyword.Length) || (0 != String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"from"); q = q.Remove (0, keyword.Length).TrimStart (null); // Next should be "meta_class" keyword = "meta_class"; if ((q.Length < keyword.Length) || (0 != String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"meta_class"); q = q.Remove (0, keyword.Length).TrimStart (null); // There may be a where clause if (0 < q.Length) { //Find "where" clause, and get the condition out keyword = "where"; if ((q.Length < keyword.Length) || (0 != String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"where"); q = q.Remove (0, keyword.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace condition = q; } else condition = String.Empty; //Empty not-applicable properties className = null; selectedProperties = null; }//schema query } ////// ///Creates a copy of the object. ////// The copied object. /// public override Object Clone () { string[] strArray = null; if (null != selectedProperties) { int count = selectedProperties.Count; if (0 < count) { strArray = new String [count]; selectedProperties.CopyTo (strArray, 0); } } if (isSchemaQuery == false) return new SelectQuery(className, condition, strArray); else return new SelectQuery(true, condition); } }//SelectQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WQL ASSOCIATORS OF data query. /// It can be used for both instances and schema queries. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class RelatedObjectQuery : WqlObjectQuery { private static readonly string tokenAssociators = "associators"; private static readonly string tokenOf = "of"; private static readonly string tokenWhere = "where"; private static readonly string tokenResultClass = "resultclass"; private static readonly string tokenAssocClass = "assocclass"; private static readonly string tokenResultRole = "resultrole"; private static readonly string tokenRole = "role"; private static readonly string tokenRequiredQualifier = "requiredqualifier"; private static readonly string tokenRequiredAssocQualifier = "requiredassocqualifier"; private static readonly string tokenClassDefsOnly = "classdefsonly"; private static readonly string tokenSchemaOnly = "schemaonly"; private bool isSchemaQuery; private string sourceObject; private string relatedClass; private string relationshipClass; private string relatedQualifier; private string relationshipQualifier; private string relatedRole; private string thisRole; private bool classDefinitionsOnly; //default constructor ///using System; /// using System.Management; /// /// // This sample demonstrates how to query all instances associated /// // with Win32_LogicalDisk='C:'. /// /// class Sample_RelatedObjectQuery /// { /// public static int Main(string[] args) { /// /// //This query requests all objects related to the 'C:' drive. /// RelatedObjectQuery relatedQuery = /// new RelatedObjectQuery("win32_logicaldisk='c:'"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(relatedQuery); /// /// foreach (ManagementObject relatedObject in searcher.Get()) { /// Console.WriteLine(relatedObject.ToString()); /// } /// /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates how to query all instances associated /// ' with Win32_LogicalDisk='C:'. /// /// Class Sample_RelatedObjectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// /// 'This query requests all objects related to the 'C:' drive. /// Dim relatedQuery As New RelatedObjectQuery("win32_logicaldisk='c:'") /// Dim searcher As New ManagementObjectSearcher(relatedQuery) /// /// Dim relatedObject As ManagementObject /// For Each relatedObject In searcher.Get() /// Console.WriteLine(relatedObject.ToString()) /// Next relatedObject /// /// Return 0 /// End Function /// End Class ///
////// Initializes a new instance /// of the ///class. /// /// public RelatedObjectQuery() :this(null) {} //parameterized constructor //ISSUE : We have 2 possible constructors that take a single string : // one that takes the full query string and the other that takes the source object path. // We resolve this by trying to parse the string, if it succeeds we assume it's the query, if // not we assume it's the source object. ///Initializes a new instance of the ///class. This is the /// default constructor. /// /// The query string or the path of the source object. ///Initializes a new instance of the ///class. If the specified string can be succesfully parsed as /// a WQL query, it is considered to be the query string; otherwise, it is assumed to be the path of the source /// object for the query. In this case, the query is assumed to be an instance query. /// public RelatedObjectQuery(string queryOrSourceObject) { if (null != queryOrSourceObject) { // Minimally determine if the string is a query or instance name. // if (queryOrSourceObject.TrimStart().StartsWith(tokenAssociators, StringComparison.OrdinalIgnoreCase)) { // Looks to be a query - do further checking. // QueryString = queryOrSourceObject; // Parse/validate; may throw. } else { // We'd like to treat it as the source object. Is it a valid // class or instance? // // Do some basic sanity checking on whether it's a class/instance name // ManagementPath p = new ManagementPath (queryOrSourceObject); if ((p.IsClass || p.IsInstance) && (p.NamespacePath.Length==0)) { SourceObject = queryOrSourceObject; isSchemaQuery = false; } else throw new ArgumentException (RC.GetString("INVALID_QUERY"),"queryOrSourceObject"); } } } /////This query retrieves all objects related to the 'mymachine' computer system /// //It specifies the full query string in the constructor /// RelatedObjectQuery q = /// new RelatedObjectQuery("associators of {Win32_ComputerSystem.Name='mymachine'}"); /// /// //or /// /// //This query retrieves all objects related to the 'Alerter' service /// //It specifies only the object of interest in the constructor /// RelatedObjectQuery q = /// new RelatedObjectQuery("Win32_Service.Name='Alerter'"); ///
///'This query retrieves all objects related to the 'mymachine' computer system /// 'It specifies the full query string in the constructor /// Dim q As New RelatedObjectQuery("associators of {Win32_ComputerSystem.Name='mymachine'}") /// /// 'or /// /// 'This query retrieves all objects related to the 'Alerter' service /// 'It specifies only the object of interest in the constructor /// Dim q As New RelatedObjectQuery("Win32_Service.Name='Alerter'") ///
////// /// The path of the source object for this query. /// The related objects class. public RelatedObjectQuery(string sourceObject, string relatedClass) : this(sourceObject, relatedClass, null, null, null, null, null, false) {} //Do we need additional variants of constructors here ?? ///Initializes a new instance of the ///class for the given source object and related class. /// The query is assumed to be an instance query (as opposed to a schema query). /// /// The path of the source object. /// The related objects required class. /// The relationship type. /// The qualifier required to be present on the related objects. /// The qualifier required to be present on the relationships. /// The role that the related objects are required to play in the relationship. /// The role that the source object is required to play in the relationship. ///Initializes a new instance of the ///class for the given set of parameters. /// The query is assumed to be an instance query (as opposed to a schema query). to return only the class definitions of the related objects; otherwise, . public RelatedObjectQuery(string sourceObject, string relatedClass, string relationshipClass, string relatedQualifier, string relationshipQualifier, string relatedRole, string thisRole, bool classDefinitionsOnly) { this.isSchemaQuery = false; this.sourceObject = sourceObject; this.relatedClass = relatedClass; this.relationshipClass = relationshipClass; this.relatedQualifier = relatedQualifier; this.relationshipQualifier = relationshipQualifier; this.relatedRole = relatedRole; this.thisRole = thisRole; this.classDefinitionsOnly = classDefinitionsOnly; BuildQuery(); } /// /// ///Initializes a new instance of the ///class for a schema query using the given set /// of parameters. This constructor is used for schema queries only: the first /// parameter must be set to /// . to indicate that this is a schema query; otherwise, . /// The path of the source class. /// The related objects' required base class. /// The relationship type. /// The qualifier required to be present on the related objects. /// The qualifier required to be present on the relationships. /// The role that the related objects are required to play in the relationship. /// The role that the source class is required to play in the relationship. public RelatedObjectQuery(bool isSchemaQuery, string sourceObject, string relatedClass, string relationshipClass, string relatedQualifier, string relationshipQualifier, string relatedRole, string thisRole) { if (isSchemaQuery == false) throw new ArgumentException(RC.GetString("INVALID_QUERY"), "isSchemaQuery"); this.isSchemaQuery = true; this.sourceObject = sourceObject; this.relatedClass = relatedClass; this.relationshipClass = relationshipClass; this.relatedQualifier = relatedQualifier; this.relationshipQualifier = relationshipQualifier; this.relatedRole = relatedRole; this.thisRole = thisRole; this.classDefinitionsOnly = false; //this parameter is not relevant for schema queries. BuildQuery(); } /// /// ///Gets or sets a value indicating whether this is a schema query or an instance query. ////// ///if this query /// should be evaluated over the schema; if the query should /// be evaluated over instances. /// /// public bool IsSchemaQuery { get { return isSchemaQuery; } set { isSchemaQuery = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new query type. ////// ///Gets or sets the source object to be used for the query. For instance /// queries, this is typically an instance path. For schema queries, this is typically a class name. ////// A string representing the path of the /// object to be used for the query. /// ////// public string SourceObject { get { return (null != sourceObject) ? sourceObject : String.Empty; } set { sourceObject = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new source object. ////// ///Gets or sets the class of the endpoint objects. ////// ///A string containing the related class /// name. ////// ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new related class. ////// public string RelatedClass { get { return (null != relatedClass) ? relatedClass : String.Empty; } set { relatedClass = value; BuildQuery(); FireIdentifierChanged(); } } ///To find all the Win32 services available on a computer, this property is set /// to "Win32_Service" : ///RelatedObjectQuery q = new RelatedObjectQuery("Win32_ComputerSystem='MySystem'"); /// q.RelatedClass = "Win32_Service"; ///
///Dim q As New RelatedObjectQuery("Win32_ComputerSystem=""MySystem""") /// q.RelatedClass = "Win32_Service" ///
////// ///Gets or sets the type of relationship (association). ////// ///A string containing the relationship /// class name. ////// ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new relationship class. ////// public string RelationshipClass { get { return (null != relationshipClass) ? relationshipClass : String.Empty; } set { relationshipClass = value; BuildQuery(); FireIdentifierChanged(); } } ///For example, for finding all the Win32 services dependent on /// a service, this property should be set to the "Win32_DependentService" association class: ///RelatedObjectQuery q = new RelatedObjectQuery("Win32_Service='TCP/IP'"); /// q.RelationshipClass = "Win32_DependentService"; ///
///Dim q As New RelatedObjectQuery("Win32_Service=""TCP/IP""") /// q.RelationshipClass = "Win32_DependentService" ///
////// ///Gets or sets a qualifier required to be defined on the related objects. ////// A string containing the name of the /// qualifier required on the related objects. /// ////// public string RelatedQualifier { get { return (null != relatedQualifier) ? relatedQualifier : String.Empty; } set { relatedQualifier = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new qualifier. ////// ///Gets or sets a qualifier required to be defined on the relationship objects. ////// ///A string containing the name of the qualifier required /// on the relationship objects. ////// public string RelationshipQualifier { get { return (null != relationshipQualifier) ? relationshipQualifier : String.Empty; } set { relationshipQualifier = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new qualifier. ////// ///Gets or sets the role that the related objects returned should be playing in the relationship. ////// ///A string containing the role of the /// related objects. ////// public string RelatedRole { get { return (null != relatedRole) ? relatedRole : String.Empty; } set { relatedRole = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new role. ////// ///Gets or sets the role that the source object should be playing in the relationship. ////// ///A string containing the role of this object. ////// public string ThisRole { get { return (null != thisRole) ? thisRole : String.Empty; } set { thisRole = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new role. ////// ///Gets or sets a value indicating that for all instances that adhere to the query, only their class definitions be returned. /// This parameter is only valid for instance queries. ////// ///if the query /// requests only class definitions of the result set; otherwise, /// . /// /// public bool ClassDefinitionsOnly { get { return classDefinitionsOnly; } set { classDefinitionsOnly = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new flag. ////// Builds the query string according to the current property values. /// protected internal void BuildQuery() { //If the source object is not set we can't build a query //Shouldn't throw here because the user may be in the process of filling in the properties... if (sourceObject == null) SetQueryString (String.Empty); if ((sourceObject == null) || (sourceObject.Length==0)) return; //"associators" clause string s = tokenAssociators + " " + tokenOf + " {" + sourceObject + "}"; //If any of the other parameters are set we need a "where" clause if (!(RelatedClass.Length==0) || !(RelationshipClass.Length==0) || !(RelatedQualifier.Length==0) || !(RelationshipQualifier.Length==0) || !(RelatedRole.Length==0) || !(ThisRole.Length==0) || classDefinitionsOnly || isSchemaQuery) { s = s + " " + tokenWhere; //"ResultClass" if (!(RelatedClass.Length==0)) s = s + " " + tokenResultClass + " = " + relatedClass; //"AssocClass" if (!(RelationshipClass.Length==0)) s = s + " " + tokenAssocClass + " = " + relationshipClass; //"ResultRole" if (!(RelatedRole.Length==0)) s = s + " " + tokenResultRole + " = " + relatedRole; //"Role" if (!(ThisRole.Length==0)) s = s + " " + tokenRole + " = " + thisRole; //"RequiredQualifier" if (!(RelatedQualifier.Length==0)) s = s + " " + tokenRequiredQualifier + " = " + relatedQualifier; //"RequiredAssocQualifier" if (!(RelationshipQualifier.Length==0)) s = s + " " + tokenRequiredAssocQualifier + " = " + relationshipQualifier; //"SchemaOnly" and "ClassDefsOnly" if (!isSchemaQuery) //this is an instance query - classDefs allowed { if (classDefinitionsOnly) s = s + " " + tokenClassDefsOnly; } else //this is a schema query, schemaonly required s = s + " " + tokenSchemaOnly; } //Set the queryString member to the built query (NB: note we set //by accessing the internal helper function rather than the property, //since we do not want to force a parse of a query we just built). SetQueryString (s); }//BuildQuery() ////// Parses the query string and sets the property values accordingly. /// /// The query string to be parsed. protected internal override void ParseQuery(string query) { // Temporary variables to hold token values until we are sure query is valid string tempSourceObject = null; string tempRelatedClass = null; string tempRelationshipClass = null; string tempRelatedRole = null; string tempThisRole = null; string tempRelatedQualifier = null; string tempRelationshipQualifier = null; bool tempClassDefsOnly = false; bool tempIsSchemaQuery = false; //Trim whitespaces string q = query.Trim(); int i; //Find "associators" clause if (0 != String.Compare(q, 0, tokenAssociators, 0, tokenAssociators.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"associators"); // Invalid query // Strip off the clause q = q.Remove(0, tokenAssociators.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace // Next token should be "of" if (0 != String.Compare(q, 0, tokenOf, 0, tokenOf.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"of"); // Invalid query // Strip off the clause and leading WS q = q.Remove(0, tokenOf.Length).TrimStart (null); // Next character should be "{" if (0 != q.IndexOf('{')) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query // Strip off the "{" and any leading WS q = q.Remove(0, 1).TrimStart(null); // Next item should be the source object if (-1 == (i = q.IndexOf('}'))) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query tempSourceObject = q.Substring(0, i).TrimEnd(null); q = q.Remove(0, i+1).TrimStart(null); // At this point we may or may not have a "where" clause if (0 < q.Length) { // Next should be the "where" clause if (0 != String.Compare (q, 0, tokenWhere, 0, tokenWhere.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"where"); // Invalid query q = q.Remove (0, tokenWhere.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace // Remaining tokens can appear in any order bool bResultClassFound = false; bool bAssocClassFound = false; bool bResultRoleFound = false; bool bRoleFound = false; bool bRequiredQualifierFound = false; bool bRequiredAssocQualifierFound = false; bool bClassDefsOnlyFound = false; bool bSchemaOnlyFound = false; // Keep looking for tokens until we are done while (true) { if ((q.Length >= tokenResultClass.Length) && (0 == String.Compare (q, 0, tokenResultClass, 0, tokenResultClass.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenResultClass, "=", ref bResultClassFound, ref tempRelatedClass); else if ((q.Length >= tokenAssocClass.Length) && (0 == String.Compare (q, 0, tokenAssocClass, 0, tokenAssocClass.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenAssocClass, "=", ref bAssocClassFound, ref tempRelationshipClass); else if ((q.Length >= tokenResultRole.Length) && (0 == String.Compare (q, 0, tokenResultRole, 0, tokenResultRole.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenResultRole, "=", ref bResultRoleFound, ref tempRelatedRole); else if ((q.Length >= tokenRole.Length) && (0 == String.Compare (q, 0, tokenRole, 0, tokenRole.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRole, "=", ref bRoleFound, ref tempThisRole); else if ((q.Length >= tokenRequiredQualifier.Length) && (0 == String.Compare (q, 0, tokenRequiredQualifier, 0, tokenRequiredQualifier.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRequiredQualifier, "=", ref bRequiredQualifierFound, ref tempRelatedQualifier); else if ((q.Length >= tokenRequiredAssocQualifier.Length) && (0 == String.Compare (q, 0, tokenRequiredAssocQualifier, 0, tokenRequiredAssocQualifier.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRequiredAssocQualifier, "=", ref bRequiredAssocQualifierFound, ref tempRelationshipQualifier); else if ((q.Length >= tokenSchemaOnly.Length) && (0 == String.Compare (q, 0, tokenSchemaOnly, 0, tokenSchemaOnly.Length, StringComparison.OrdinalIgnoreCase))) { ParseToken (ref q, tokenSchemaOnly, ref bSchemaOnlyFound); tempIsSchemaQuery = true; } else if ((q.Length >= tokenClassDefsOnly.Length) && (0 == String.Compare (q, 0, tokenClassDefsOnly, 0, tokenClassDefsOnly.Length, StringComparison.OrdinalIgnoreCase))) { ParseToken (ref q, tokenClassDefsOnly, ref bClassDefsOnlyFound); tempClassDefsOnly = true; } else if (0 == q.Length) break; // done else throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Unrecognized token } //Can't have both classDefsOnly and schemaOnly if (bSchemaOnlyFound && bClassDefsOnlyFound) throw new ArgumentException(RC.GetString("INVALID_QUERY")); } // Getting here means we parsed successfully. Assign the values. sourceObject = tempSourceObject; relatedClass = tempRelatedClass; relationshipClass = tempRelationshipClass; relatedRole = tempRelatedRole; thisRole = tempThisRole; relatedQualifier = tempRelatedQualifier; relationshipQualifier = tempRelationshipQualifier; classDefinitionsOnly = tempClassDefsOnly; isSchemaQuery = tempIsSchemaQuery; }//ParseQuery() //ICloneable ////// ///Creates a copy of the object. ////// The copied object. /// public override object Clone() { if (isSchemaQuery == false) return new RelatedObjectQuery(sourceObject, relatedClass, relationshipClass, relatedQualifier, relationshipQualifier, relatedRole, thisRole, classDefinitionsOnly); else return new RelatedObjectQuery(true, sourceObject, relatedClass, relationshipClass, relatedQualifier, relationshipQualifier, relatedRole, thisRole); } }//RelatedObjectQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WQL REFERENCES OF data query. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class RelationshipQuery : WqlObjectQuery { private static readonly string tokenReferences = "references"; private static readonly string tokenOf = "of"; private static readonly string tokenWhere = "where"; private static readonly string tokenResultClass = "resultclass"; private static readonly string tokenRole = "role"; private static readonly string tokenRequiredQualifier = "requiredqualifier"; private static readonly string tokenClassDefsOnly = "classdefsonly"; private static readonly string tokenSchemaOnly = "schemaonly"; private string sourceObject; private string relationshipClass; private string relationshipQualifier; private string thisRole; private bool classDefinitionsOnly; private bool isSchemaQuery; //default constructor ///The following example searches for all objects related to the /// 'C:' drive object: ///using System; /// using System.Management; /// /// class Sample_RelationshipQuery /// { /// public static int Main(string[] args) { /// RelationshipQuery query = /// new RelationshipQuery("references of {Win32_LogicalDisk.DeviceID='C:'}"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(query); /// /// foreach (ManagementObject assoc in searcher.Get()) { /// Console.WriteLine("Association class = " + assoc["__CLASS"]); /// } /// /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// Class Sample_RelatedObjectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// Dim query As New RelationshipQuery("references of {Win32_LogicalDisk.DeviceID='C:'}") /// Dim searcher As New ManagementObjectSearcher(query) /// Dim assoc As ManagementObject /// /// For Each assoc In searcher.Get() /// Console.WriteLine("Association class = " & assoc("__CLASS")) /// Next assoc /// /// Return 0 /// End Function /// End Class ///
////// Initializes a new instance /// of the ///class. /// /// public RelationshipQuery() :this(null) {} //parameterized constructor //ISSUE : We have 2 possible constructors that take a single string : // one that takes the full query string and the other that takes the source object path. // We resolve this by trying to parse the string, if it succeeds we assume it's the query, if // not we assume it's the source object. ///Initializes a new instance of the ///class. This is the default constructor. /// /// The query string or the class name for this query. ///Initializes a new instance of the ///class. If the specified string can be succesfully parsed as /// a WQL query, it is considered to be the query string; otherwise, it is assumed to be the path of the source /// object for the query. In this case, the query is assumed to be an instances query. /// public RelationshipQuery(string queryOrSourceObject) { if (null != queryOrSourceObject) { // Minimally determine if the string is a query or instance name. // if (queryOrSourceObject.TrimStart().StartsWith(tokenReferences, StringComparison.OrdinalIgnoreCase)) { // Looks to be a query - do further checking. // QueryString = queryOrSourceObject; // Parse/validate; may throw. } else { // We'd like to treat it as the source object. Is it a valid // class or instance? // Do some basic sanity checking on whether it's a class/instance name // ManagementPath p = new ManagementPath (queryOrSourceObject); if ((p.IsClass || p.IsInstance) && (p.NamespacePath.Length==0)) { SourceObject = queryOrSourceObject; isSchemaQuery = false; } else throw new ArgumentException (RC.GetString("INVALID_QUERY"),"queryOrSourceObject"); } } } ///This example shows the two different ways to use this constructor: /////Full query string is specified to the constructor /// RelationshipQuery q = new RelationshipQuery("references of {Win32_ComputerSystem.Name='mymachine'}"); /// /// //Only the object of interest is specified to the constructor /// RelationshipQuery q = new RelationshipQuery("Win32_Service.Name='Alerter'"); ///
///'Full query string is specified to the constructor /// Dim q As New RelationshipQuery("references of {Win32_ComputerSystem.Name='mymachine'}") /// /// 'Only the object of interest is specified to the constructor /// Dim q As New RelationshipQuery("Win32_Service.Name='Alerter'") ///
////// /// The path of the source object for this query. /// The type of relationship for which to query. public RelationshipQuery(string sourceObject, string relationshipClass) : this(sourceObject, relationshipClass, null, null, false) {} //Do we need additional variants of constructors here ?? ///Initializes a new instance of the ///class for the given source object and relationship class. /// The query is assumed to be an instance query (as opposed to a schema query). /// /// The path of the source object for this query. /// The type of relationship for which to query. /// A qualifier required to be present on the relationship object. /// The role that the source object is required to play in the relationship. /// When this method returns, it contains a boolean that indicates that only class definitions for the resulting objects are returned. public RelationshipQuery(string sourceObject, string relationshipClass, string relationshipQualifier, string thisRole, bool classDefinitionsOnly) { this.isSchemaQuery = false; this.sourceObject = sourceObject; this.relationshipClass = relationshipClass; this.relationshipQualifier = relationshipQualifier; this.thisRole = thisRole; this.classDefinitionsOnly = classDefinitionsOnly; BuildQuery(); } ///Initializes a new instance of the ///class for the given set of parameters. /// The query is assumed to be an instance query (as opposed to a schema query). /// ///Initializes a new instance of the ///class for a schema query using the given set /// of parameters. This constructor is used for schema queries only, so the first /// parameter must be /// . to indicate that this is a schema query; otherwise, . /// The path of the source class for this query. /// The type of relationship for which to query. /// A qualifier required to be present on the relationship class. /// The role that the source class is required to play in the relationship. public RelationshipQuery(bool isSchemaQuery, string sourceObject, string relationshipClass, string relationshipQualifier, string thisRole) { if (isSchemaQuery == false) throw new ArgumentException(RC.GetString("INVALID_QUERY"), "isSchemaQuery"); this.isSchemaQuery = true; this.sourceObject = sourceObject; this.relationshipClass = relationshipClass; this.relationshipQualifier = relationshipQualifier; this.thisRole = thisRole; this.classDefinitionsOnly = false; //this parameter is not relevant for schema queries. BuildQuery(); } /// /// ///Gets or sets a value indicating whether this query is a schema query or an instance query. ////// ///if this query /// should be evaluated over the schema; if the query should /// be evaluated over instances. /// /// public bool IsSchemaQuery { get { return isSchemaQuery; } set { isSchemaQuery = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new query type. ////// ///Gets or sets the source object for this query. ////// A string representing the path of /// the object to be used for the query. /// ////// public string SourceObject { get { return (null != sourceObject) ? sourceObject : String.Empty; } set { sourceObject = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new source object. ////// ///Gets or sets the class of the relationship objects wanted in the query. ////// A string containing the relationship /// class name. /// ////// public string RelationshipClass { get { return (null != relationshipClass) ? relationshipClass : String.Empty; } set { relationshipClass = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new class. ////// ///Gets or sets a qualifier required on the relationship objects. ////// A string containing the name of the /// qualifier required on the relationship objects. /// ////// public string RelationshipQualifier { get { return (null != relationshipQualifier) ? relationshipQualifier : String.Empty; } set { relationshipQualifier = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new qualifier. ////// ///Gets or sets the role of the source object in the relationship. ////// A string containing the role of this /// object. /// ////// public string ThisRole { get { return (null != thisRole) ? thisRole : String.Empty; } set { thisRole = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new role. ////// ///Gets or sets a value indicating that only the class definitions of the relevant relationship objects be returned. ////// ////// if the query requests only class definitions of the /// result set; otherwise, . /// public bool ClassDefinitionsOnly { get { return classDefinitionsOnly; } set { classDefinitionsOnly = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any previous /// value stored in the object. As a side-effect, the query string is /// rebuilt to reflect the new flag. ////// Builds the query string according to the current property values. /// protected internal void BuildQuery() { //If the source object is not set we can't build a query //Shouldn't throw here because the user may be in the process of filling in the properties... if (sourceObject == null) SetQueryString(String.Empty); if ((sourceObject == null) || (sourceObject.Length==0)) return; //"references" clause string s = tokenReferences + " " + tokenOf + " {" + sourceObject + "}"; //If any of the other parameters are set we need a "where" clause if (!(RelationshipClass.Length==0) || !(RelationshipQualifier.Length==0) || !(ThisRole.Length==0) || classDefinitionsOnly || isSchemaQuery) { s = s + " " + tokenWhere; //"ResultClass" if (!(RelationshipClass.Length==0)) s = s + " " + tokenResultClass + " = " + relationshipClass; //"Role" if (!(ThisRole.Length==0)) s = s + " " + tokenRole + " = " + thisRole; //"RequiredQualifier" if (!(RelationshipQualifier.Length==0)) s = s + " " + tokenRequiredQualifier + " = " + relationshipQualifier; //"SchemaOnly" and "ClassDefsOnly" if (!isSchemaQuery) //this is an instance query - classDefs allowed { if (classDefinitionsOnly) s = s + " " + tokenClassDefsOnly; } else //this is a schema query, schemaonly required s = s + " " + tokenSchemaOnly; } //Set the queryString member to the built query (NB: note we set //by accessing the internal helper function rather than the property, //since we do not want to force a parse of a query we just built). SetQueryString (s); } //BuildQuery() ////// Parses the query string and sets the property values accordingly. /// /// The query string to be parsed. protected internal override void ParseQuery(string query) { // Temporary variables to hold token values until we are sure query is valid string tempSourceObject = null; string tempRelationshipClass = null; string tempThisRole = null; string tempRelationshipQualifier = null; bool tempClassDefsOnly = false; bool tempSchemaOnly = false; //Trim whitespaces string q = query.Trim(); int i; //Find "references" clause if (0 != String.Compare(q, 0, tokenReferences, 0, tokenReferences.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"references"); // Invalid query // Strip off the clause q = q.Remove(0, tokenReferences.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace // Next token should be "of" if (0 != String.Compare(q, 0, tokenOf, 0, tokenOf.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"of"); // Invalid query // Strip off the clause and leading WS q = q.Remove(0, tokenOf.Length).TrimStart (null); // Next character should be "{" if (0 != q.IndexOf('{')) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query // Strip off the "{" and any leading WS q = q.Remove(0, 1).TrimStart(null); // Next item should be the source object if (-1 == (i = q.IndexOf('}'))) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query tempSourceObject = q.Substring(0, i).TrimEnd(null); q = q.Remove(0, i+1).TrimStart(null); // At this point we may or may not have a "where" clause if (0 < q.Length) { // Next should be the "where" clause if (0 != String.Compare (q, 0, tokenWhere, 0, tokenWhere.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"where"); // Invalid query q = q.Remove (0, tokenWhere.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace // Remaining tokens can appear in any order bool bResultClassFound = false; bool bRoleFound = false; bool bRequiredQualifierFound = false; bool bClassDefsOnlyFound = false; bool bSchemaOnlyFound = false; // Keep looking for tokens until we are done while (true) { if ((q.Length >= tokenResultClass.Length) && (0 == String.Compare (q, 0, tokenResultClass, 0, tokenResultClass.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenResultClass, "=", ref bResultClassFound, ref tempRelationshipClass); else if ((q.Length >= tokenRole.Length) && (0 == String.Compare (q, 0, tokenRole, 0, tokenRole.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRole, "=", ref bRoleFound, ref tempThisRole); else if ((q.Length >= tokenRequiredQualifier.Length) && (0 == String.Compare (q, 0, tokenRequiredQualifier, 0, tokenRequiredQualifier.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRequiredQualifier, "=", ref bRequiredQualifierFound, ref tempRelationshipQualifier); else if ((q.Length >= tokenClassDefsOnly.Length) && (0 == String.Compare (q, 0, tokenClassDefsOnly, 0, tokenClassDefsOnly.Length, StringComparison.OrdinalIgnoreCase))) { ParseToken (ref q, tokenClassDefsOnly, ref bClassDefsOnlyFound); tempClassDefsOnly = true; } else if ((q.Length >= tokenSchemaOnly.Length) && (0 == String.Compare (q, 0, tokenSchemaOnly, 0, tokenSchemaOnly.Length, StringComparison.OrdinalIgnoreCase))) { ParseToken (ref q, tokenSchemaOnly, ref bSchemaOnlyFound); tempSchemaOnly = true; } else if (0 == q.Length) break; // done else throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Unrecognized token } //Can't have both classDefsOnly and schemaOnly if (tempClassDefsOnly && tempSchemaOnly) throw new ArgumentException(RC.GetString("INVALID_QUERY")); } // Getting here means we parsed successfully. Assign the values. sourceObject = tempSourceObject; relationshipClass = tempRelationshipClass; thisRole = tempThisRole; relationshipQualifier = tempRelationshipQualifier; classDefinitionsOnly = tempClassDefsOnly; isSchemaQuery = tempSchemaOnly; }//ParseQuery() //ICloneable ////// ///Creates a copy of the object. ////// The copied object. /// public override object Clone() { if (isSchemaQuery == false) return new RelationshipQuery(sourceObject, relationshipClass, relationshipQualifier, thisRole, classDefinitionsOnly); else return new RelationshipQuery(true, sourceObject, relationshipClass, relationshipQualifier, thisRole); } }//RelationshipQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WMI event query in WQL format. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class WqlEventQuery : EventQuery { private static readonly string tokenSelectAll = "select * "; private string eventClassName; private TimeSpan withinInterval; private string condition; private TimeSpan groupWithinInterval; private StringCollection groupByPropertyList; private string havingCondition; //default constructor ///using System; /// using System.Management; /// /// // This sample demonstrates how to subscribe to an event /// // using a WQL event query. /// /// class Sample_EventQuery /// { /// public static int Main(string[] args) /// { /// //For this example, we make sure we have an arbitrary class on root\default /// ManagementClass newClass = new ManagementClass( /// "root\\default", /// String.Empty, /// null); /// newClass["__Class"] = "TestWql"; /// newClass.Put(); /// /// //Create a query object for watching for class deletion events /// WqlEventQuery eventQuery = new WqlEventQuery("select * from __classdeletionevent"); /// /// //Initialize an event watcher object with this query /// ManagementEventWatcher watcher = new ManagementEventWatcher( /// new ManagementScope("root/default"), /// eventQuery); /// /// //Set up a handler for incoming events /// MyHandler handler = new MyHandler(); /// watcher.EventArrived += new EventArrivedEventHandler(handler.Arrived); /// /// //Start watching for events /// watcher.Start(); /// /// //For this example, we delete the class to trigger an event /// newClass.Delete(); /// /// //Nothing better to do - we loop to wait for an event to arrive. /// while (!handler.IsArrived) { /// System.Threading.Thread.Sleep(1000); /// } /// /// //In this example we only want to wait for one event, so we can stop watching /// watcher.Stop(); /// /// return 0; /// } /// /// public class MyHandler /// { /// private bool isArrived = false; /// /// //Handles the event when it arrives /// public void Arrived(object sender, EventArrivedEventArgs e) { /// ManagementBaseObject eventArg = (ManagementBaseObject)(e.NewEvent["TargetClass"]); /// Console.WriteLine("Class Deleted = " + eventArg["__CLASS"]); /// isArrived = true; /// } /// /// //Used to determine whether the event has arrived or not. /// public bool IsArrived { /// get { /// return isArrived; /// } /// } /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates how to subscribe an event /// ' using a WQL event query. /// /// Class Sample_EventQuery /// Public Shared Sub Main() /// /// 'For this example, we make sure we have an arbitrary class on root\default /// Dim newClass As New ManagementClass( _ /// "root\default", _ /// String.Empty, Nothing) /// newClass("__Class") = "TestWql" /// newClass.Put() /// /// 'Create a query object for watching for class deletion events /// Dim eventQuery As New WqlEventQuery("select * from __classdeletionevent") /// /// 'Initialize an event watcher object with this query /// Dim watcher As New ManagementEventWatcher( _ /// New ManagementScope("root/default"), _ /// eventQuery) /// /// 'Set up a handler for incoming events /// Dim handler As New MyHandler() /// AddHandler watcher.EventArrived, AddressOf handler.Arrived /// /// 'Start watching for events /// watcher.Start() /// /// 'For this example, we delete the class to trigger an event /// newClass.Delete() /// /// 'Nothing better to do - we loop to wait for an event to arrive. /// While Not handler.IsArrived /// Console.Write("0") /// System.Threading.Thread.Sleep(1000) /// End While /// /// 'In this example we only want to wait for one event, so we can stop watching /// watcher.Stop() /// /// End Sub /// /// Public Class MyHandler /// Private _isArrived As Boolean = False /// /// 'Handles the event when it arrives /// Public Sub Arrived(sender As Object, e As EventArrivedEventArgs) /// Dim eventArg As ManagementBaseObject = CType( _ /// e.NewEvent("TargetClass"), _ /// ManagementBaseObject) /// Console.WriteLine(("Class Deleted = " + eventArg("__CLASS"))) /// _isArrived = True /// End Sub /// /// 'Used to determine whether the event has arrived or not. /// Public ReadOnly Property IsArrived() As Boolean /// Get /// Return _isArrived /// End Get /// End Property /// End Class /// End Class ///
////// ///Initializes a new instance of the ///class. /// public WqlEventQuery() : this(null, TimeSpan.Zero, null, TimeSpan.Zero, null, null) {} //parameterized constructors //ISSUE : We have 2 possible constructors that take a single string : // one that takes the full query string and the other that takes the class name. // We resolve this by trying to parse the string, if it succeeds we assume it's the query, if // not we assume it's the class name. ///Initializes a new instance of the ////// class. This is the default /// constructor. /// /// The string representing either the entire event query or the name of the event class to query. The object will try to parse the string as a valid event query. If unsuccessful, the parser will assume that the parameter represents an event class name. ///Initializes a new instance of the ////// class based on the given /// query string or event class name. /// public WqlEventQuery(string queryOrEventClassName) { groupByPropertyList = new StringCollection(); if (null != queryOrEventClassName) { // Minimally determine if the string is a query or event class name. // if (queryOrEventClassName.TrimStart().StartsWith(tokenSelectAll, StringComparison.OrdinalIgnoreCase)) { QueryString = queryOrEventClassName; // Parse/validate; may throw. } else { // Do some basic sanity checking on whether it's a class name // ManagementPath p = new ManagementPath (queryOrEventClassName); if (p.IsClass && (p.NamespacePath.Length==0)) { EventClassName = queryOrEventClassName; } else throw new ArgumentException (RC.GetString("INVALID_QUERY"),"queryOrEventClassName"); } } } ///The two options below are equivalent : /////Full query string specified to the constructor /// WqlEventQuery q = new WqlEventQuery("SELECT * FROM MyEvent"); /// /// //Only relevant event class name specified to the constructor /// WqlEventQuery q = new WqlEventQuery("MyEvent"); //results in the same query as above. ///
///'Full query string specified to the constructor /// Dim q As New WqlEventQuery("SELECT * FROM MyEvent") /// /// 'Only relevant event class name specified to the constructor /// Dim q As New WqlEventQuery("MyEvent") 'results in the same query as above ///
////// /// The name of the event class to query. /// The condition to apply to events of the specified class. ///Initializes a new instance of the ////// class for the /// specified event class name, with the specified condition. /// public WqlEventQuery(string eventClassName, string condition) : this(eventClassName, TimeSpan.Zero, condition, TimeSpan.Zero, null, null) {} ///This example shows how to create an event query that contains a condition in /// addition to the event class : /////Requests all "MyEvent" events where the event's properties /// //match the specified condition /// WqlEventQuery q = new WqlEventQuery("MyEvent", "FirstProp < 20 and SecondProp = 'red'"); ///
///'Requests all "MyEvent" events where the event's properties /// 'match the specified condition /// Dim q As New WqlEventQuery("MyEvent", "FirstProp < 20 and SecondProp = 'red'") ///
////// /// The name of the event class to query. /// A timespan value specifying the latency acceptable for receiving this event. This value is used in cases where there is no explicit event provider for the query requested, and WMI is required to poll for the condition. This interval is the maximum amount of time that can pass before notification of an event must be delivered. ///Initializes a new instance of the ////// class for the specified /// event class, with the specified latency time. /// public WqlEventQuery(string eventClassName, TimeSpan withinInterval): this(eventClassName, withinInterval, null, TimeSpan.Zero, null, null) {} ///This example shows creating an event query that contains /// a /// time interval. /////Requests all instance creation events, with a specified latency of /// //10 seconds. The query created is "SELECT * FROM __InstanceCreationEvent WITHIN 10" /// WqlEventQuery q = new WqlEventQuery("__InstanceCreationEvent", /// new TimeSpan(0,0,10)); ///
///'Requests all instance creation events, with a specified latency of /// '10 seconds. The query created is "SELECT * FROM __InstanceCreationEvent WITHIN 10" /// Dim t As New TimeSpan(0,0,10) /// Dim q As New WqlEventQuery("__InstanceCreationEvent", t) ///
////// /// The name of the event class to query. /// A timespan value specifying the latency acceptable for receiving this event. This value is used in cases where there is no explicit event provider for the query requested and WMI is required to poll for the condition. This interval is the maximum amount of time that can pass before notification of an event must be delivered. /// The condition to apply to events of the specified class. ///Initializes a new instance of the ////// class with the specified /// event class name, polling interval, and condition. /// public WqlEventQuery(string eventClassName, TimeSpan withinInterval, string condition) : this(eventClassName, withinInterval, condition, TimeSpan.Zero, null, null) {} ///This example creates the event query: "SELECT * FROM /// ///WITHIN 10 WHERE /// ISA ", which means /// "send notification of the creation of /// instances, /// with a 10-second polling interval." //Requests notification of the creation of Win32_Service instances with a 10 second /// //allowed latency. /// WqlEventQuery q = new WqlEventQuery("__InstanceCreationEvent", /// new TimeSpan(0,0,10), /// "TargetInstance isa 'Win32_Service'"); ///
///'Requests notification of the creation of Win32_Service instances with a 10 second /// 'allowed latency. /// Dim t As New TimeSpan(0,0,10) /// Dim q As New WqlEventQuery("__InstanceCreationEvent", _ /// t, _ /// "TargetInstance isa ""Win32_Service""") ///
////// /// The name of the event class to query. /// The condition to apply to events of the specified class. /// The specified interval at which WMI sends one aggregate event, rather than many events. ///Initializes a new instance of the ////// class with the specified /// event class name, condition, and grouping interval. /// public WqlEventQuery(string eventClassName, string condition, TimeSpan groupWithinInterval) : this(eventClassName, TimeSpan.Zero, condition, groupWithinInterval, null, null) {} ///This example creates the event query: "SELECT * FROM /// ///WHERE = 5 /// GROUP WITHIN 10", which means "send notification of events of type /// , in which the /// is equal to 5, but send an aggregate event in /// a /// 10-second interval." //Sends an aggregate of the requested events every 10 seconds /// WqlEventQuery q = new WqlEventQuery("FrequentEvent", /// "InterestingProperty = 5", /// new TimeSpan(0,0,10)); ///
///'Sends an aggregate of the requested events every 10 seconds /// Dim t As New TimeSpan(0,0,10) /// Dim q As New WqlEventQuery("FrequentEvent", _ /// "InterestingProperty = 5", _ /// t) ///
////// /// The name of the event class to query. /// The condition to apply to events of the specified class. /// The specified interval at which WMI sends one aggregate event, rather than many events. /// The properties in the event class by which the events should be grouped. ///Initializes a new instance of the ////// class with the specified event class /// name, condition, grouping interval, and grouping properties. /// public WqlEventQuery(string eventClassName, string condition, TimeSpan groupWithinInterval, string[] groupByPropertyList) : this(eventClassName, TimeSpan.Zero, condition, groupWithinInterval, groupByPropertyList, null) {} ///This example creates the event query: "SELECT * FROM /// ///WHERE = 'MyBoss' GROUP /// WITHIN 300 BY ", which means "send notification when /// new email from a particular sender has arrived within the last 10 minutes, /// combined with other events that have the same value in the /// /// property." //Requests "EmailEvent" events where the Sender property is "MyBoss", and /// //groups them based on importance /// String[] props = {"Importance"}; /// WqlEventQuery q = new WqlEventQuery("EmailEvent", /// "Sender = 'MyBoss'", /// new TimeSpan(0,10,0), /// props); ///
///'Requests "EmailEvent" events where the Sender property is "MyBoss", and /// 'groups them based on importance /// Dim props() As String = {"Importance"} /// Dim t As New TimeSpan(0,10,0) /// Dim q As New WqlEventQuery("EmailEvent", _ /// "Sender = ""MyBoss""", _ /// t, _ /// props) ///
////// /// The name of the event class on which to be queried. /// A timespan value specifying the latency acceptable for receiving this event. This value is used in cases where there is no explicit event provider for the query requested, and WMI is required to poll for the condition. This interval is the maximum amount of time that can pass before notification of an event must be delivered. /// The condition to apply to events of the specified class. /// The specified interval at which WMI sends one aggregate event, rather than many events. /// The properties in the event class by which the events should be grouped. /// The condition to apply to the number of events. ///Initializes a new instance of the ////// class with the specified event class /// name, condition, grouping interval, grouping properties, and specified number of events. /// public WqlEventQuery(string eventClassName, TimeSpan withinInterval, string condition, TimeSpan groupWithinInterval, string[] groupByPropertyList, string havingCondition) { this.eventClassName = eventClassName; this.withinInterval = withinInterval; this.condition = condition; this.groupWithinInterval = groupWithinInterval; this.groupByPropertyList = new StringCollection (); if (null != groupByPropertyList) this.groupByPropertyList.AddRange (groupByPropertyList); this.havingCondition = havingCondition; BuildQuery(); } //QueryLanguage property is read-only in this class (does this work ??) ///This example creates the event query: "SELECT * FROM /// ///WHERE /// ISA GROUP WITHIN 300 BY /// HAVING /// > 15" which means "deliver aggregate events /// only if the number of events received from the /// same source exceeds 15." //Requests sending aggregated events if the number of events exceeds 15. /// String[] props = {"TargetInstance.SourceName"}; /// WqlEventQuery q = new WqlEventQuery("__InstanceCreationEvent", /// "TargetInstance isa 'Win32_NTLogEvent'", /// new TimeSpan(0,10,0), /// props, /// "NumberOfEvents >15"); ///
///'Requests sending aggregated events if the number of events exceeds 15. /// Dim props() As String = {"TargetInstance.SourceName"}; /// Dim t As New TimeSpan(0,10,0) /// Dim q As WqlEventQuery("__InstanceCreationEvent", _ /// "TargetInstance isa ""Win32_NTLogEvent""", _ /// t, _ /// props, _ /// "NumberOfEvents >15") ///
////// ///Gets or sets the language of the query. ////// public override string QueryLanguage { get {return base.QueryLanguage;} } ///The value of this property in this /// object is always "WQL". ////// ///Gets or sets the string representing the query. ////// A string representing the query. /// public override string QueryString { get { // We need to force a rebuild as we may not have detected // a change to selected properties BuildQuery (); return base.QueryString; } set { base.QueryString = value; } } ////// ///Gets or sets the event class to query. ////// A string containing the name of the /// event class to query. /// ////// ///Setting this property value overrides any previous value /// stored /// in the object. The query string is rebuilt to /// reflect the new class name. ////// public string EventClassName { get { return (null != eventClassName) ? eventClassName : String.Empty; } set { eventClassName = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM ". WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "MyEvent"; ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "MyEvent" ///
////// ///Gets or sets the condition to be applied to events of the /// specified class. ////// ///The condition is represented as a /// string, containing one or more clauses of the form: <propName> /// <operator> <value> combined with and/or operators. <propName> /// must represent a property defined on the event class specified in this query. ////// ///Setting this property value overrides any previous value /// stored in the object. The query string is rebuilt to /// reflect the new condition. ////// public string Condition { get { return (null != condition) ? condition : String.Empty; } set { condition = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM WHERE /// > 8". WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "MyEvent"; /// q.Condition = "PropVal > 8"; ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "MyEvent" /// q.Condition = "PropVal > 8" ///
////// ///Gets or sets the polling interval to be used in this query. ////// ///Null, if there is no polling involved; otherwise, a /// valid ////// value if polling is required. /// ///This property should only be set in cases /// where there is no event provider for the event requested, and WMI is required to /// poll for the requested condition. ///Setting this property value overrides any previous value /// stored in /// the object. The query string is rebuilt to reflect the new interval. ////// public TimeSpan WithinInterval { get { return withinInterval; } set { withinInterval = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM WITHIN 10 WHERE > 8". WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "__InstanceModificationEvent"; /// q.Condition = "PropVal > 8"; /// q.WithinInterval = new TimeSpan(0,0,10); ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "__InstanceModificationEvent" /// q.Condition = "PropVal > 8" /// q.WithinInterval = New TimeSpan(0,0,10) ///
////// ///Gets or sets the interval to be used for grouping events of /// the same type. ////// ///Null, if there is no /// grouping involved; otherwise, the interval in which WMI should group events of /// the same type. ////// ///Setting this property value overrides any previous value stored in /// the object. The query string is rebuilt to reflect the new interval. ////// public TimeSpan GroupWithinInterval { get { return groupWithinInterval; } set { groupWithinInterval = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM WHERE /// > 8 GROUP WITHIN 10", which means "send notification /// of all events where the /// property is greater than 8, and aggregate these events within 10-second intervals." WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "MyEvent"; /// q.Condition = "PropVal > 8"; /// q.GroupWithinInterval = new TimeSpan(0,0,10); ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "MyEvent" /// q.Condition = "PropVal > 8" /// q.GroupWithinInterval = New TimeSpan(0,0,10) ///
////// ///Gets or sets properties in the event to be used for /// grouping events of the same type. ////// ////// Null, if no grouping is required; otherwise, a collection of event /// property names. ////// ///Setting this property value overrides any previous value stored in /// the object. The query string is rebuilt to reflect the new grouping. ////// public StringCollection GroupByPropertyList { get { return groupByPropertyList; } set { // A tad painful since StringCollection doesn't support ICloneable StringCollection src = (StringCollection)value; StringCollection dst = new StringCollection (); foreach (String s in src) dst.Add (s); groupByPropertyList = dst; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM GROUP /// WITHIN 300 BY ", which means "send notification of all /// events, aggregated by the property, within 10-minute intervals." WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "EmailEvent"; /// q.GroupWithinInterval = new TimeSpan(0,10,0); /// q.GroupByPropertyList = new StringCollection(); /// q.GroupByPropertyList.Add("Sender"); ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "EmailEvent" /// q.GroupWithinInterval = New TimeSpan(0,10,0) /// q.GroupByPropertyList = New StringCollection() /// q.GroupByPropertyList.Add("Sender") ///
////// ///Gets or sets the condition to be applied to the aggregation of /// events, based on the number of events received. ////// ////// Null, if no aggregation or no condition should be applied; /// otherwise, a condition of the form "NumberOfEvents <operator> /// <value>". ////// ///Setting this property value overrides any previous value stored in /// the object. The query string is rebuilt to reflect the new grouping condition. ////// public string HavingCondition { get { return (null != havingCondition) ? havingCondition : String.Empty; } set { havingCondition = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM GROUP /// WITHIN 300 HAVING > 5", which means "send /// notification of all events, aggregated within /// 10-minute intervals, if there are more than 5 occurrences." WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "EmailEvent"; /// q.GroupWithinInterval = new TimeSpan(0,10,0); /// q.HavingCondition = "NumberOfEvents > 5"; ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "EmailEvent" /// q.GroupWithinInterval = new TimeSpan(0,10,0) /// q.HavingCondition = "NumberOfEvents > 5" ///
////// Builds the query string according to the current property values. /// protected internal void BuildQuery() { //If the event class name is not set we can't build a query //This shouldn't throw because the user may be in the process of setting properties... if ((eventClassName == null) || (eventClassName.Length==0)) { SetQueryString (String.Empty); return; } //Select clause string s = tokenSelectAll; //no property list allowed here... //From clause s = s + "from " + eventClassName; //Within clause if (withinInterval != TimeSpan.Zero) s = s + " within " + withinInterval.TotalSeconds.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Double))); //Where clause if (!(Condition.Length==0)) s = s + " where " + condition; //Group within clause if (groupWithinInterval != TimeSpan.Zero) { s = s + " group within " + groupWithinInterval.TotalSeconds.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Double))); //Group By clause if ((null != groupByPropertyList) && (0 < groupByPropertyList.Count)) { int count = groupByPropertyList.Count; s = s + " by "; for (int i=0; i= keyword.Length) && (0 == String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) { string intervalString = null; bFound = false; ParseToken(ref q, keyword, null, ref bFound, ref intervalString); withinInterval = TimeSpan.FromSeconds(((IConvertible)intervalString).ToDouble(null)); } //Find "group within" clause keyword = "group within "; if ((q.Length >= keyword.Length) && ((i = q.ToLower(CultureInfo.InvariantCulture).IndexOf(keyword, StringComparison.Ordinal)) != -1)) //found { //Separate the part of the string before this - that should be the "where" clause w = q.Substring(0, i).Trim(); q = q.Remove(0, i); string intervalString = null; bFound=false; ParseToken(ref q, keyword, null, ref bFound, ref intervalString); groupWithinInterval = TimeSpan.FromSeconds(((IConvertible)intervalString).ToDouble(null)); //Find "By" subclause keyword = "by "; if ((q.Length >= keyword.Length) && (0 == String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) { q = q.Remove(0, keyword.Length); if (null != groupByPropertyList) groupByPropertyList.Clear (); else groupByPropertyList = new StringCollection (); //get the property list while (true) { if ((i = q.IndexOf(',')) > 0) { tempProp = q.Substring(0, i); q = q.Remove(0, i+1).TrimStart(null); tempProp = tempProp.Trim(); if (tempProp.Length>0) groupByPropertyList.Add(tempProp); } else { //last property in the list if ((i = q.IndexOf(' ')) > 0) { tempProp = q.Substring(0, i); q = q.Remove(0, i).TrimStart(null); groupByPropertyList.Add(tempProp); break; } else //end of the query { groupByPropertyList.Add(q); return; } } } //while } //by //Find "Having" subclause keyword = "having "; bFound = false; if ((q.Length >= keyword.Length) && (0 == String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) { //the rest until the end is assumed to be the having condition q = q.Remove(0, keyword.Length); if (q.Length == 0) //bad query throw new ArgumentException(RC.GetString("INVALID_QUERY"),"having"); havingCondition = q; } } else //No "group within" then everything should be the "where" clause w = q.Trim(); //Find "where" clause keyword = "where "; if ((w.Length >= keyword.Length) && (0 == String.Compare (w, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) //where clause exists { condition = w.Substring(keyword.Length); } }//ParseQuery() //ICloneable /// /// ///Creates a copy of the object. ////// The copied object. /// public override object Clone() { string[] strArray = null; if (null != groupByPropertyList) { int count = groupByPropertyList.Count; if (0 < count) { strArray = new String [count]; groupByPropertyList.CopyTo (strArray, 0); } } return new WqlEventQuery(eventClassName, withinInterval, condition, groupWithinInterval, strArray, havingCondition); } }//WqlEventQuery ////// Converts a String to a ManagementQuery /// class ManagementQueryConverter : ExpandableObjectConverter { ////// Determines if this converter can convert an object in the given source type to the native type of the converter. /// /// An ITypeDescriptorContext that provides a format context. /// A Type that represents the type you wish to convert from. ////// public override Boolean CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if ((sourceType == typeof(ManagementQuery))) { return true; } return base.CanConvertFrom(context,sourceType); } ///true if this converter can perform the conversion; otherwise, false. ////// Gets a value indicating whether this converter can convert an object to the given destination type using the context. /// /// An ITypeDescriptorContext that provides a format context. /// A Type that represents the type you wish to convert to. ////// public override Boolean CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if ((destinationType == typeof(InstanceDescriptor))) { return true; } return base.CanConvertTo(context,destinationType); } ///true if this converter can perform the conversion; otherwise, false. ////// Converts the given object to another type. The most common types to convert /// are to and from a string object. The default implementation will make a call /// to ToString on the object if the object is valid and if the destination /// type is string. If this cannot convert to the desitnation type, this will /// throw a NotSupportedException. /// /// An ITypeDescriptorContext that provides a format context. /// A CultureInfo object. If a null reference (Nothing in Visual Basic) is passed, the current culture is assumed. /// The Object to convert. /// The Type to convert the value parameter to. ///An Object that represents the converted value. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == null) { throw new ArgumentNullException("destinationType"); } if (value is EventQuery && destinationType == typeof(InstanceDescriptor)) { EventQuery obj = ((EventQuery)(value)); ConstructorInfo ctor = typeof(EventQuery).GetConstructor(new Type[] {typeof(System.String)}); if (ctor != null) { return new InstanceDescriptor(ctor, new object[] {obj.QueryString}); } } if (value is ObjectQuery && destinationType == typeof(InstanceDescriptor)) { ObjectQuery obj = ((ObjectQuery)(value)); ConstructorInfo ctor = typeof(ObjectQuery).GetConstructor(new Type[] {typeof(System.String)}); if (ctor != null) { return new InstanceDescriptor(ctor, new object[] {obj.QueryString}); } } return base.ConvertTo(context,culture,value,destinationType); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections.Specialized; using WbemUtilities_v1; using WbemClient_v1; using System.Globalization; using System.Reflection; using System.ComponentModel.Design.Serialization; using System.ComponentModel; using System.ComponentModel.Design; namespace System.Management { //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Provides an abstract base class for all management query objects. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// [TypeConverter(typeof(ManagementQueryConverter ))] public abstract class ManagementQuery : ICloneable { internal const string DEFAULTQUERYLANGUAGE = "WQL"; internal static readonly string tokenSelect = "select "; // Keep trailing space char. //Used when any public property on this object is changed, to signal //to the containing object that it needs to be refreshed. internal event IdentifierChangedEventHandler IdentifierChanged; //Fires IdentifierChanged event internal void FireIdentifierChanged() { if (IdentifierChanged != null) IdentifierChanged(this, null); } private string queryLanguage; private string queryString; internal void SetQueryString (string qString) { queryString = qString; } //default constructor internal ManagementQuery() : this(DEFAULTQUERYLANGUAGE, null) {} //parameterized constructors internal ManagementQuery(string query) : this(DEFAULTQUERYLANGUAGE, query) {} internal ManagementQuery(string language, string query) { QueryLanguage = language; QueryString = query; } ///This class is abstract; only /// derivatives of it are actually used in the API. ////// Parses the query string and sets the property values accordingly. /// /// The query string to be parsed. protected internal virtual void ParseQuery (string query) {} // //properties // ////// ///Gets or sets the query in text format. ////// public virtual string QueryString { get {return (null != queryString) ? queryString : String.Empty;} set { if (queryString != value) { ParseQuery (value); // this may throw queryString = value; FireIdentifierChanged (); } } } ///If the query object is /// constructed with no parameters, the property is null until specifically set. If the /// object was constructed with a specified query, the property returns the specified /// query string. ////// ///Gets or sets the query language used in the query /// string, defining the format of the query string. ////// public virtual String QueryLanguage { get {return (null != queryLanguage) ? queryLanguage : String.Empty;} set { if (queryLanguage != value) { queryLanguage = value; FireIdentifierChanged (); } } } //ICloneable ///Can be set to any supported query /// language. "WQL" is the only value supported intrinsically by WMI. ////// ///Returns a copy of the object. ////// The cloned object. /// public abstract object Clone(); internal static void ParseToken (ref string q, string token, string op, ref bool bTokenFound, ref string tokenValue) { if (bTokenFound) throw new ArgumentException (RC.GetString("INVALID_QUERY_DUP_TOKEN")); // Invalid query - duplicate token bTokenFound = true; q = q.Remove (0, token.Length).TrimStart (null); // Next character should be the operator if any if (op != null) { if (0 != q.IndexOf(op, StringComparison.Ordinal)) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query // Strip off the op and any leading WS q = q.Remove(0, op.Length).TrimStart(null); } if (0 == q.Length) throw new ArgumentException (RC.GetString("INVALID_QUERY_NULL_TOKEN")); // Invalid query - token has no value // Next token should be the token value - look for terminating WS // or end of string int i; if (-1 == (i = q.IndexOf (' '))) i = q.Length; // No WS => consume entire string tokenValue = q.Substring (0, i); q = q.Remove (0, tokenValue.Length).TrimStart(null); } internal static void ParseToken (ref string q, string token, ref bool bTokenFound) { if (bTokenFound) throw new ArgumentException (RC.GetString("INVALID_QUERY_DUP_TOKEN")); // Invalid query - duplicate token bTokenFound = true; q = q.Remove (0, token.Length).TrimStart (null); } }//ManagementQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a management query that returns instances or classes. ////// ///This class or its derivatives are used to specify a /// query in the ///. Use /// a more specific query class whenever possible. /// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class ObjectQuery : ManagementQuery { ///using System; /// using System.Management; /// /// // This sample demonstrates creating a query. /// /// class Sample_ObjectQuery /// { /// public static int Main(string[] args) /// { /// ObjectQuery objectQuery = new ObjectQuery("select * from Win32_Share"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(objectQuery); /// foreach (ManagementObject share in searcher.Get()) /// { /// Console.WriteLine("Share = " + share["Name"]); /// } /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates creating a query. /// /// Class Sample_ObjectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// Dim objectQuery As New ObjectQuery("select * from Win32_Share") /// Dim searcher As New ManagementObjectSearcher(objectQuery) /// Dim share As ManagementObject /// For Each share In searcher.Get() /// Console.WriteLine("Share = " & share("Name")) /// Next share /// Return 0 /// End Function /// End Class ///
////// ///Initializes a new instance of the ////// class. /// public ObjectQuery() : base() {} ///Initializes a new instance of the ////// class with no initialized values. This /// is the default constructor. /// /// The string representation of the query. public ObjectQuery(string query) : base(query) {} ///Initializes a new instance of the ////// class /// for a specific query string. /// /// The query language in which this query is specified. /// The string representation of the query. public ObjectQuery(string language, string query) : base(language, query) {} //ICloneable ///Initializes a new instance of the ////// class for a specific /// query string and language. /// ///Returns a copy of the object. ////// The cloned object. /// public override object Clone () { return new ObjectQuery(QueryLanguage, QueryString); } }//ObjectQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WMI event query. ////// ///Objects of this class or its derivatives are used in /// ///to subscribe to /// WMI events. Use more specific derivatives of this class whenever possible. /// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class EventQuery : ManagementQuery { ///using System; /// using System.Management; /// /// // This sample demonstrates how to subscribe to an event /// // using the EventQuery object. /// /// class Sample_EventQuery /// { /// public static int Main(string[] args) /// { /// //For this example, we make sure we have an arbitrary class on root\default /// ManagementClass newClass = new ManagementClass( /// "root\\default", /// String.Empty, /// null); /// newClass["__Class"] = "TestWql"; /// newClass.Put(); /// /// //Create a query object for watching for class deletion events /// EventQuery eventQuery = new EventQuery("select * from __classdeletionevent"); /// /// //Initialize an event watcher object with this query /// ManagementEventWatcher watcher = new ManagementEventWatcher( /// new ManagementScope("root/default"), /// eventQuery); /// /// //Set up a handler for incoming events /// MyHandler handler = new MyHandler(); /// watcher.EventArrived += new EventArrivedEventHandler(handler.Arrived); /// /// //Start watching for events /// watcher.Start(); /// /// //For this example, we delete the class to trigger an event /// newClass.Delete(); /// /// //Nothing better to do - we loop to wait for an event to arrive. /// while (!handler.IsArrived) { /// System.Threading.Thread.Sleep(1000); /// } /// /// //In this example we only want to wait for one event, so we can stop watching /// watcher.Stop(); /// /// //Get some values from the event. /// //Note: this can also be done in the event handler. /// ManagementBaseObject eventArg = /// (ManagementBaseObject)(handler.ReturnedArgs.NewEvent["TargetClass"]); /// Console.WriteLine("Class Deleted = " + eventArg["__CLASS"]); /// /// return 0; /// } /// /// public class MyHandler /// { /// private bool isArrived = false; /// private EventArrivedEventArgs args; /// /// //Handles the event when it arrives /// public void Arrived(object sender, EventArrivedEventArgs e) { /// args = e; /// isArrived = true; /// } /// /// //Public property to get at the event information stored in the handler /// public EventArrivedEventArgs ReturnedArgs { /// get { /// return args; /// } /// } /// /// //Used to determine whether the event has arrived or not. /// public bool IsArrived { /// get { /// return isArrived; /// } /// } /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates how to subscribe an event /// ' using the EventQuery object. /// /// Class Sample_EventQuery /// Public Shared Sub Main() /// /// 'For this example, we make sure we have an arbitrary class on root\default /// Dim newClass As New ManagementClass( _ /// "root\default", _ /// String.Empty, Nothing) /// newClass("__Class") = "TestWql" /// newClass.Put() /// /// 'Create a query object for watching for class deletion events /// Dim eventQuery As New EventQuery("select * from __classdeletionevent") /// /// 'Initialize an event watcher object with this query /// Dim watcher As New ManagementEventWatcher( _ /// New ManagementScope("root/default"), _ /// eventQuery) /// /// 'Set up a handler for incoming events /// Dim handler As New MyHandler() /// AddHandler watcher.EventArrived, AddressOf handler.Arrived /// /// 'Start watching for events /// watcher.Start() /// /// 'For this example, we delete the class to trigger an event /// newClass.Delete() /// /// 'Nothing better to do - we loop to wait for an event to arrive. /// While Not handler.IsArrived /// Console.Write("0") /// System.Threading.Thread.Sleep(1000) /// End While /// /// 'In this example we only want to wait for one event, so we can stop watching /// watcher.Stop() /// /// 'Get some values from the event /// 'Note: this can also be done in the event handler. /// Dim eventArg As ManagementBaseObject = CType( _ /// handler.ReturnedArgs.NewEvent("TargetClass"), _ /// ManagementBaseObject) /// Console.WriteLine(("Class Deleted = " + eventArg("__CLASS"))) /// /// End Sub /// /// Public Class MyHandler /// Private _isArrived As Boolean = False /// Private args As EventArrivedEventArgs /// /// 'Handles the event when it arrives /// Public Sub Arrived(sender As Object, e As EventArrivedEventArgs) /// args = e /// _isArrived = True /// End Sub /// /// 'Public property to get at the event information stored in the handler /// Public ReadOnly Property ReturnedArgs() As EventArrivedEventArgs /// Get /// Return args /// End Get /// End Property /// /// 'Used to determine whether the event has arrived or not. /// Public ReadOnly Property IsArrived() As Boolean /// Get /// Return _isArrived /// End Get /// End Property /// End Class /// End Class ///
////// ///Initializes a new instance of the ////// class. /// public EventQuery() : base() {} ///Initializes a new instance of the ////// class. This is the /// default constructor. /// /// A textual representation of the event query. public EventQuery(string query) : base(query) {} ///Initializes a new instance of the ////// class for the specified query. /// /// The language in which the query string is specified. /// The string representation of the query. public EventQuery(string language, string query) : base(language, query) {} //ICloneable ///Initializes a new instance of the ////// class for the specified /// language and query. /// ///Returns a copy of the object. ////// The cloned object. /// public override object Clone() { return new EventQuery(QueryLanguage, QueryString); } }//EventQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WMI data query in WQL format. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class WqlObjectQuery : ObjectQuery { //constructors //Here we don't take a language argument but hard-code it to WQL in the base class ///using System; /// using System.Management; /// /// // This sample demonstrates how to use a WqlObjectQuery class to /// // perform an object query. /// /// class Sample_WqlObjectQuery /// { /// public static int Main(string[] args) { /// WqlObjectQuery objectQuery = new WqlObjectQuery("select * from Win32_Share"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(objectQuery); /// /// foreach (ManagementObject share in searcher.Get()) { /// Console.WriteLine("Share = " + share["Name"]); /// } /// /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrate how to use a WqlObjectQuery class to /// ' perform an object query. /// /// Class Sample_WqlObjectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// Dim objectQuery As New WqlObjectQuery("select * from Win32_Share") /// Dim searcher As New ManagementObjectSearcher(objectQuery) /// /// Dim share As ManagementObject /// For Each share In searcher.Get() /// Console.WriteLine("Share = " & share("Name")) /// Next share /// /// Return 0 /// End Function /// End Class ///
////// ///Initializes a new instance of the ///class. /// public WqlObjectQuery() : base(null) {} ///Initializes a new instance of the ///class. This is the /// default constructor. /// ///Initializes a new instance of the ///class initialized to the /// specified query. The representation of the data query. public WqlObjectQuery(string query) : base(query) {} //QueryLanguage property is read-only in this class (does this work ??) ////// ///Gets or sets the language of the query. ////// public override string QueryLanguage { get {return base.QueryLanguage;} } //ICloneable ///The value of this /// property is always "WQL". ////// ///Creates a copy of the object. ////// The copied object. /// public override object Clone() { return new WqlObjectQuery(QueryString); } }//WqlObjectQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WQL SELECT data query. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class SelectQuery : WqlObjectQuery { private bool isSchemaQuery = false; private string className; private string condition; private StringCollection selectedProperties; //default constructor ///using System; /// using System.Management; /// /// // This sample demonstrates how to perform a WQL select query. /// /// class Sample_SelectQuery /// { /// public static int Main(string[] args) { /// SelectQuery selectQuery = new SelectQuery("win32_logicaldisk"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(selectQuery); /// /// foreach (ManagementObject disk in searcher.Get()) { /// Console.WriteLine(disk.ToString()); /// } /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates how to perform a WQL select query. /// /// Class Sample_SelectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// Dim selectQuery As New SelectQuery("win32_logicaldisk") /// Dim searcher As New ManagementObjectSearcher(selectQuery) /// /// Dim disk As ManagementObject /// For Each disk In searcher.Get() /// Console.WriteLine(disk.ToString()) /// Next disk /// /// Return 0 /// End Function /// End Class ///
////// ///Initializes a new instance of the ////// class. /// public SelectQuery() :this(null) {} //parameterized constructors //ISSUE : We have 2 possible constructors that take a single string : // one that takes the full query string and the other that takes the class name. // We resolve this by trying to parse the string, if it succeeds we assume it's the query, if // not we assume it's the class name. ///Initializes a new instance of the ////// class. This is the /// default constructor. /// /// The entire query or the class name to use in the query. The parser in this class attempts to parse the string as a valid WQL SELECT query. If the parser is unsuccessful, it assumes the string is a class name. ///Initializes a new instance of the ///class for the specified /// query or the specified class name. /// public SelectQuery(string queryOrClassName) { selectedProperties = new StringCollection (); if (null != queryOrClassName) { // Minimally determine if the string is a query or class name. // if (queryOrClassName.TrimStart().StartsWith(tokenSelect, StringComparison.OrdinalIgnoreCase)) { // Looks to be a query - do further checking. // QueryString = queryOrClassName; // Parse/validate; may throw. } else { // Do some basic sanity checking on whether it's a class name // ManagementPath p = new ManagementPath (queryOrClassName); if (p.IsClass && (p.NamespacePath.Length==0)) ClassName = queryOrClassName; else throw new ArgumentException (RC.GetString("INVALID_QUERY"),"queryOrClassName"); } } } ///SelectQuery s = new SelectQuery("SELECT * FROM Win32_Service WHERE State='Stopped'); /// /// or /// /// //This is equivalent to "SELECT * FROM Win32_Service" /// SelectQuery s = new SelectQuery("Win32_Service"); ///
///Dim s As New SelectQuery("SELECT * FROM Win32_Service WHERE State='Stopped') /// /// or /// /// //This is equivalent to "SELECT * FROM Win32_Service" /// Dim s As New SelectQuery("Win32_Service") ///
////// /// The name of the class to select in the query. /// The condition to be applied in the query. ///Initializes a new instance of the ////// class with the specified /// class name and condition. /// public SelectQuery(string className, string condition) : this(className, condition, null) {} ///SelectQuery s = new SelectQuery("Win32_Process", "HandleID=1234"); ///
///Dim s As New SelectQuery("Win32_Process", "HandleID=1234") ///
////// /// The name of the class from which to select. /// The condition to be applied to instances of the selected class. /// An array of property names to be returned in the query results. ///Initializes a new instance of the ////// class with the specified /// class name and condition, selecting only the specified properties. /// public SelectQuery(string className, string condition, string[] selectedProperties) : base () { this.isSchemaQuery = false; this.className = className; this.condition = condition; this.selectedProperties = new StringCollection (); if (null != selectedProperties) this.selectedProperties.AddRange (selectedProperties); BuildQuery(); } ///String[] properties = {"VariableName", "VariableValue"}; /// /// SelectQuery s = new SelectQuery("Win32_Environment", /// "User='<system>'", /// properties); ///
///Dim properties As String[] = {"VariableName", "VariableValue"} /// /// Dim s As New SelectQuery("Win32_Environment", _ /// "User=""<system>""", _ /// properties) ///
////// ///Initializes a new instance of the ////// class for a schema query, optionally specifying a condition. For schema queries, /// only the parameter is valid: /// and /// are not supported and are ignored. to indicate that this is a schema query; otherwise, . A value is invalid in this constructor. /// The condition to be applied to form the result set of classes. /// /// public SelectQuery(bool isSchemaQuery, string condition) : base () { if (isSchemaQuery == false) throw new ArgumentException(RC.GetString("INVALID_QUERY"), "isSchemaQuery"); this.isSchemaQuery = true; this.className = null; this.condition = condition; this.selectedProperties = null; BuildQuery(); } ///SelectQuery s = new SelectQuery(true, "__CLASS = 'Win32_Service'"); ///
///Dim s As New SelectQuery(true, "__CLASS = ""Win32_Service""") ///
////// ///Gets or sets the query in the ///, in string form. /// ///A string representing the query. ////// ///Setting this /// property value overrides any previous value stored in the object. In addition, setting this /// property causes the other members of the object to be updated when the string /// is reparsed. ////// public override string QueryString { get { // We need to force a rebuild as we may not have detected // a change to selected properties BuildQuery (); return base.QueryString;} set { base.QueryString = value; } } ///SelectQuery s = new SelectQuery(); /// s.QueryString = "SELECT * FROM Win32_LogicalDisk"; ///
///Dim s As New SelectQuery() /// s.QueryString = "SELECT * FROM Win32_LogicalDisk" ///
////// ///Gets or sets a value indicating whether this query is a schema query or an instances query. ////// ////// if this query /// should be evaluated over the schema; if the query should /// be evaluated over instances. /// public bool IsSchemaQuery { get { return isSchemaQuery; } set { isSchemaQuery = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new query type. ////// ///Gets or sets the class name to be selected from in the query. ////// ///A string representing the name of the /// class. ////// ///Setting this property value /// overrides any previous value stored in the object. The query string is /// rebuilt to reflect the new class name. ////// public string ClassName { get { return (null != className) ? className : String.Empty; } set { className = value; BuildQuery(); FireIdentifierChanged(); } } ///SelectQuery s = new SelectQuery("SELECT * FROM Win32_LogicalDisk"); /// Console.WriteLine(s.QueryString); //output is : SELECT * FROM Win32_LogicalDisk /// /// s.ClassName = "Win32_Process"; /// Console.WriteLine(s.QueryString); //output is : SELECT * FROM Win32_Process ///
///Dim s As New SelectQuery("SELECT * FROM Win32_LogicalDisk") /// Console.WriteLine(s.QueryString) 'output is : SELECT * FROM Win32_LogicalDisk /// /// s.ClassName = "Win32_Process" /// Console.WriteLine(s.QueryString) 'output is : SELECT * FROM Win32_Process ///
////// ///Gets or sets the condition to be applied in the SELECT /// query. ////// A string containing the condition to /// be applied in the SELECT query. /// ////// public string Condition { get { return (null != condition) ? condition : String.Empty; } set { condition = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any previous value /// stored in the object. The query string is rebuilt to reflect the new /// condition. ////// ///Gets or sets an array of property names to be /// selected in the query. ////// ///A ///containing the names of the /// properties to be selected in the query. /// public StringCollection SelectedProperties { get { return selectedProperties; } set { if (null != value) { // A tad painful since StringCollection doesn't support ICloneable StringCollection src = (StringCollection)value; StringCollection dst = new StringCollection (); foreach (String s in src) dst.Add (s); selectedProperties = dst; } else selectedProperties = new StringCollection (); BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any previous value stored /// in the object. The query string is rebuilt to reflect the new /// properties. ////// Builds the query string according to the current property values. /// protected internal void BuildQuery() { string s; if (isSchemaQuery == false) //this is an instances query { //If the class name is not set we can't build a query //Shouldn't throw here because the user may be in the process of filling in the properties... if (className == null) SetQueryString (String.Empty); if ((className == null) || (className.Length==0)) return; //Select clause s = tokenSelect; //If properties are specified list them if ((null != selectedProperties) && (0 < selectedProperties.Count)) { int count = selectedProperties.Count; for (int i = 0; i < count; i++) s = s + selectedProperties[i] + ((i == (count - 1)) ? " " : ","); } else s = s + "* "; //From clause s = s + "from " + className; } else //this is a schema query, ignore className or selectedProperties. { //Select clause s = "select * from meta_class"; } //Where clause if ((Condition != null) && (Condition.Length != 0)) s = s + " where " + condition; //Set the queryString member to the built query (NB: note we set //by accessing the internal helper function rather than the property, //since we do not want to force a parse of a query we just built). SetQueryString (s); } ////// Parses the query string and sets the property values accordingly. /// /// The query string to be parsed. protected internal override void ParseQuery(string query) { //Clear out previous property values className = null; condition = null; if (selectedProperties != null) selectedProperties.Clear(); //Trim whitespaces string q = query.Trim(); bool bFound = false; string tempProp; int i; if (isSchemaQuery == false) //instances query { //Find "select" clause and get the property list if exists string keyword = tokenSelect; if ((q.Length >= keyword.Length) && (String.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase) == 0)) //select clause found { ParseToken (ref q, keyword, ref bFound); if (q[0] != '*') //we have properties { if (null != selectedProperties) selectedProperties.Clear (); else selectedProperties = new StringCollection (); //get the property list while (true) { if ((i = q.IndexOf(',')) > 0) { tempProp = q.Substring(0, i); q = q.Remove(0, i+1).TrimStart(null); tempProp = tempProp.Trim(); if (tempProp.Length>0) selectedProperties.Add(tempProp); } else { //last property in the list if ((i = q.IndexOf(' ')) > 0) { tempProp = q.Substring(0, i); q = q.Remove(0, i).TrimStart(null); selectedProperties.Add(tempProp); break; } else //bad query throw new ArgumentException(RC.GetString("INVALID_QUERY")); } } //while } else q = q.Remove(0, 1).TrimStart(null); } else //select clause has to be there, otherwise the parsing fails throw new ArgumentException(RC.GetString("INVALID_QUERY")); //Find "from" clause, get the class name and remove the clause keyword = "from "; bFound = false; if ((q.Length >= keyword.Length) && (String.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase) == 0)) //from clause found ParseToken(ref q, keyword, null, ref bFound, ref className); else //from clause has to be there, otherwise the parsing fails throw new ArgumentException(RC.GetString("INVALID_QUERY")); //Find "where" clause, get the condition out and remove the clause keyword = "where "; if ((q.Length >= keyword.Length) && (String.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase) == 0)) //where clause exists { condition = q.Substring(keyword.Length).Trim(); } } //if isSchemaQuery == false else //this is a schema query { //Find "select" clause and make sure it's the right syntax string keyword = "select"; // Should start with "select" if ((q.Length < keyword.Length) || (0 != String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"select"); q = q.Remove (0, keyword.Length).TrimStart (null); // Next should be a '*' if (0 != q.IndexOf ('*', 0)) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"*"); q = q.Remove (0, 1).TrimStart (null); // Next should be "from" keyword = "from"; if ((q.Length < keyword.Length) || (0 != String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"from"); q = q.Remove (0, keyword.Length).TrimStart (null); // Next should be "meta_class" keyword = "meta_class"; if ((q.Length < keyword.Length) || (0 != String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"meta_class"); q = q.Remove (0, keyword.Length).TrimStart (null); // There may be a where clause if (0 < q.Length) { //Find "where" clause, and get the condition out keyword = "where"; if ((q.Length < keyword.Length) || (0 != String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) throw new ArgumentException (RC.GetString("INVALID_QUERY"),"where"); q = q.Remove (0, keyword.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace condition = q; } else condition = String.Empty; //Empty not-applicable properties className = null; selectedProperties = null; }//schema query } ////// ///Creates a copy of the object. ////// The copied object. /// public override Object Clone () { string[] strArray = null; if (null != selectedProperties) { int count = selectedProperties.Count; if (0 < count) { strArray = new String [count]; selectedProperties.CopyTo (strArray, 0); } } if (isSchemaQuery == false) return new SelectQuery(className, condition, strArray); else return new SelectQuery(true, condition); } }//SelectQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WQL ASSOCIATORS OF data query. /// It can be used for both instances and schema queries. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class RelatedObjectQuery : WqlObjectQuery { private static readonly string tokenAssociators = "associators"; private static readonly string tokenOf = "of"; private static readonly string tokenWhere = "where"; private static readonly string tokenResultClass = "resultclass"; private static readonly string tokenAssocClass = "assocclass"; private static readonly string tokenResultRole = "resultrole"; private static readonly string tokenRole = "role"; private static readonly string tokenRequiredQualifier = "requiredqualifier"; private static readonly string tokenRequiredAssocQualifier = "requiredassocqualifier"; private static readonly string tokenClassDefsOnly = "classdefsonly"; private static readonly string tokenSchemaOnly = "schemaonly"; private bool isSchemaQuery; private string sourceObject; private string relatedClass; private string relationshipClass; private string relatedQualifier; private string relationshipQualifier; private string relatedRole; private string thisRole; private bool classDefinitionsOnly; //default constructor ///using System; /// using System.Management; /// /// // This sample demonstrates how to query all instances associated /// // with Win32_LogicalDisk='C:'. /// /// class Sample_RelatedObjectQuery /// { /// public static int Main(string[] args) { /// /// //This query requests all objects related to the 'C:' drive. /// RelatedObjectQuery relatedQuery = /// new RelatedObjectQuery("win32_logicaldisk='c:'"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(relatedQuery); /// /// foreach (ManagementObject relatedObject in searcher.Get()) { /// Console.WriteLine(relatedObject.ToString()); /// } /// /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates how to query all instances associated /// ' with Win32_LogicalDisk='C:'. /// /// Class Sample_RelatedObjectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// /// 'This query requests all objects related to the 'C:' drive. /// Dim relatedQuery As New RelatedObjectQuery("win32_logicaldisk='c:'") /// Dim searcher As New ManagementObjectSearcher(relatedQuery) /// /// Dim relatedObject As ManagementObject /// For Each relatedObject In searcher.Get() /// Console.WriteLine(relatedObject.ToString()) /// Next relatedObject /// /// Return 0 /// End Function /// End Class ///
////// Initializes a new instance /// of the ///class. /// /// public RelatedObjectQuery() :this(null) {} //parameterized constructor //ISSUE : We have 2 possible constructors that take a single string : // one that takes the full query string and the other that takes the source object path. // We resolve this by trying to parse the string, if it succeeds we assume it's the query, if // not we assume it's the source object. ///Initializes a new instance of the ///class. This is the /// default constructor. /// /// The query string or the path of the source object. ///Initializes a new instance of the ///class. If the specified string can be succesfully parsed as /// a WQL query, it is considered to be the query string; otherwise, it is assumed to be the path of the source /// object for the query. In this case, the query is assumed to be an instance query. /// public RelatedObjectQuery(string queryOrSourceObject) { if (null != queryOrSourceObject) { // Minimally determine if the string is a query or instance name. // if (queryOrSourceObject.TrimStart().StartsWith(tokenAssociators, StringComparison.OrdinalIgnoreCase)) { // Looks to be a query - do further checking. // QueryString = queryOrSourceObject; // Parse/validate; may throw. } else { // We'd like to treat it as the source object. Is it a valid // class or instance? // // Do some basic sanity checking on whether it's a class/instance name // ManagementPath p = new ManagementPath (queryOrSourceObject); if ((p.IsClass || p.IsInstance) && (p.NamespacePath.Length==0)) { SourceObject = queryOrSourceObject; isSchemaQuery = false; } else throw new ArgumentException (RC.GetString("INVALID_QUERY"),"queryOrSourceObject"); } } } /////This query retrieves all objects related to the 'mymachine' computer system /// //It specifies the full query string in the constructor /// RelatedObjectQuery q = /// new RelatedObjectQuery("associators of {Win32_ComputerSystem.Name='mymachine'}"); /// /// //or /// /// //This query retrieves all objects related to the 'Alerter' service /// //It specifies only the object of interest in the constructor /// RelatedObjectQuery q = /// new RelatedObjectQuery("Win32_Service.Name='Alerter'"); ///
///'This query retrieves all objects related to the 'mymachine' computer system /// 'It specifies the full query string in the constructor /// Dim q As New RelatedObjectQuery("associators of {Win32_ComputerSystem.Name='mymachine'}") /// /// 'or /// /// 'This query retrieves all objects related to the 'Alerter' service /// 'It specifies only the object of interest in the constructor /// Dim q As New RelatedObjectQuery("Win32_Service.Name='Alerter'") ///
////// /// The path of the source object for this query. /// The related objects class. public RelatedObjectQuery(string sourceObject, string relatedClass) : this(sourceObject, relatedClass, null, null, null, null, null, false) {} //Do we need additional variants of constructors here ?? ///Initializes a new instance of the ///class for the given source object and related class. /// The query is assumed to be an instance query (as opposed to a schema query). /// /// The path of the source object. /// The related objects required class. /// The relationship type. /// The qualifier required to be present on the related objects. /// The qualifier required to be present on the relationships. /// The role that the related objects are required to play in the relationship. /// The role that the source object is required to play in the relationship. ///Initializes a new instance of the ///class for the given set of parameters. /// The query is assumed to be an instance query (as opposed to a schema query). to return only the class definitions of the related objects; otherwise, . public RelatedObjectQuery(string sourceObject, string relatedClass, string relationshipClass, string relatedQualifier, string relationshipQualifier, string relatedRole, string thisRole, bool classDefinitionsOnly) { this.isSchemaQuery = false; this.sourceObject = sourceObject; this.relatedClass = relatedClass; this.relationshipClass = relationshipClass; this.relatedQualifier = relatedQualifier; this.relationshipQualifier = relationshipQualifier; this.relatedRole = relatedRole; this.thisRole = thisRole; this.classDefinitionsOnly = classDefinitionsOnly; BuildQuery(); } /// /// ///Initializes a new instance of the ///class for a schema query using the given set /// of parameters. This constructor is used for schema queries only: the first /// parameter must be set to /// . to indicate that this is a schema query; otherwise, . /// The path of the source class. /// The related objects' required base class. /// The relationship type. /// The qualifier required to be present on the related objects. /// The qualifier required to be present on the relationships. /// The role that the related objects are required to play in the relationship. /// The role that the source class is required to play in the relationship. public RelatedObjectQuery(bool isSchemaQuery, string sourceObject, string relatedClass, string relationshipClass, string relatedQualifier, string relationshipQualifier, string relatedRole, string thisRole) { if (isSchemaQuery == false) throw new ArgumentException(RC.GetString("INVALID_QUERY"), "isSchemaQuery"); this.isSchemaQuery = true; this.sourceObject = sourceObject; this.relatedClass = relatedClass; this.relationshipClass = relationshipClass; this.relatedQualifier = relatedQualifier; this.relationshipQualifier = relationshipQualifier; this.relatedRole = relatedRole; this.thisRole = thisRole; this.classDefinitionsOnly = false; //this parameter is not relevant for schema queries. BuildQuery(); } /// /// ///Gets or sets a value indicating whether this is a schema query or an instance query. ////// ///if this query /// should be evaluated over the schema; if the query should /// be evaluated over instances. /// /// public bool IsSchemaQuery { get { return isSchemaQuery; } set { isSchemaQuery = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new query type. ////// ///Gets or sets the source object to be used for the query. For instance /// queries, this is typically an instance path. For schema queries, this is typically a class name. ////// A string representing the path of the /// object to be used for the query. /// ////// public string SourceObject { get { return (null != sourceObject) ? sourceObject : String.Empty; } set { sourceObject = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new source object. ////// ///Gets or sets the class of the endpoint objects. ////// ///A string containing the related class /// name. ////// ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new related class. ////// public string RelatedClass { get { return (null != relatedClass) ? relatedClass : String.Empty; } set { relatedClass = value; BuildQuery(); FireIdentifierChanged(); } } ///To find all the Win32 services available on a computer, this property is set /// to "Win32_Service" : ///RelatedObjectQuery q = new RelatedObjectQuery("Win32_ComputerSystem='MySystem'"); /// q.RelatedClass = "Win32_Service"; ///
///Dim q As New RelatedObjectQuery("Win32_ComputerSystem=""MySystem""") /// q.RelatedClass = "Win32_Service" ///
////// ///Gets or sets the type of relationship (association). ////// ///A string containing the relationship /// class name. ////// ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new relationship class. ////// public string RelationshipClass { get { return (null != relationshipClass) ? relationshipClass : String.Empty; } set { relationshipClass = value; BuildQuery(); FireIdentifierChanged(); } } ///For example, for finding all the Win32 services dependent on /// a service, this property should be set to the "Win32_DependentService" association class: ///RelatedObjectQuery q = new RelatedObjectQuery("Win32_Service='TCP/IP'"); /// q.RelationshipClass = "Win32_DependentService"; ///
///Dim q As New RelatedObjectQuery("Win32_Service=""TCP/IP""") /// q.RelationshipClass = "Win32_DependentService" ///
////// ///Gets or sets a qualifier required to be defined on the related objects. ////// A string containing the name of the /// qualifier required on the related objects. /// ////// public string RelatedQualifier { get { return (null != relatedQualifier) ? relatedQualifier : String.Empty; } set { relatedQualifier = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new qualifier. ////// ///Gets or sets a qualifier required to be defined on the relationship objects. ////// ///A string containing the name of the qualifier required /// on the relationship objects. ////// public string RelationshipQualifier { get { return (null != relationshipQualifier) ? relationshipQualifier : String.Empty; } set { relationshipQualifier = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new qualifier. ////// ///Gets or sets the role that the related objects returned should be playing in the relationship. ////// ///A string containing the role of the /// related objects. ////// public string RelatedRole { get { return (null != relatedRole) ? relatedRole : String.Empty; } set { relatedRole = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new role. ////// ///Gets or sets the role that the source object should be playing in the relationship. ////// ///A string containing the role of this object. ////// public string ThisRole { get { return (null != thisRole) ? thisRole : String.Empty; } set { thisRole = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new role. ////// ///Gets or sets a value indicating that for all instances that adhere to the query, only their class definitions be returned. /// This parameter is only valid for instance queries. ////// ///if the query /// requests only class definitions of the result set; otherwise, /// . /// /// public bool ClassDefinitionsOnly { get { return classDefinitionsOnly; } set { classDefinitionsOnly = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new flag. ////// Builds the query string according to the current property values. /// protected internal void BuildQuery() { //If the source object is not set we can't build a query //Shouldn't throw here because the user may be in the process of filling in the properties... if (sourceObject == null) SetQueryString (String.Empty); if ((sourceObject == null) || (sourceObject.Length==0)) return; //"associators" clause string s = tokenAssociators + " " + tokenOf + " {" + sourceObject + "}"; //If any of the other parameters are set we need a "where" clause if (!(RelatedClass.Length==0) || !(RelationshipClass.Length==0) || !(RelatedQualifier.Length==0) || !(RelationshipQualifier.Length==0) || !(RelatedRole.Length==0) || !(ThisRole.Length==0) || classDefinitionsOnly || isSchemaQuery) { s = s + " " + tokenWhere; //"ResultClass" if (!(RelatedClass.Length==0)) s = s + " " + tokenResultClass + " = " + relatedClass; //"AssocClass" if (!(RelationshipClass.Length==0)) s = s + " " + tokenAssocClass + " = " + relationshipClass; //"ResultRole" if (!(RelatedRole.Length==0)) s = s + " " + tokenResultRole + " = " + relatedRole; //"Role" if (!(ThisRole.Length==0)) s = s + " " + tokenRole + " = " + thisRole; //"RequiredQualifier" if (!(RelatedQualifier.Length==0)) s = s + " " + tokenRequiredQualifier + " = " + relatedQualifier; //"RequiredAssocQualifier" if (!(RelationshipQualifier.Length==0)) s = s + " " + tokenRequiredAssocQualifier + " = " + relationshipQualifier; //"SchemaOnly" and "ClassDefsOnly" if (!isSchemaQuery) //this is an instance query - classDefs allowed { if (classDefinitionsOnly) s = s + " " + tokenClassDefsOnly; } else //this is a schema query, schemaonly required s = s + " " + tokenSchemaOnly; } //Set the queryString member to the built query (NB: note we set //by accessing the internal helper function rather than the property, //since we do not want to force a parse of a query we just built). SetQueryString (s); }//BuildQuery() ////// Parses the query string and sets the property values accordingly. /// /// The query string to be parsed. protected internal override void ParseQuery(string query) { // Temporary variables to hold token values until we are sure query is valid string tempSourceObject = null; string tempRelatedClass = null; string tempRelationshipClass = null; string tempRelatedRole = null; string tempThisRole = null; string tempRelatedQualifier = null; string tempRelationshipQualifier = null; bool tempClassDefsOnly = false; bool tempIsSchemaQuery = false; //Trim whitespaces string q = query.Trim(); int i; //Find "associators" clause if (0 != String.Compare(q, 0, tokenAssociators, 0, tokenAssociators.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"associators"); // Invalid query // Strip off the clause q = q.Remove(0, tokenAssociators.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace // Next token should be "of" if (0 != String.Compare(q, 0, tokenOf, 0, tokenOf.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"of"); // Invalid query // Strip off the clause and leading WS q = q.Remove(0, tokenOf.Length).TrimStart (null); // Next character should be "{" if (0 != q.IndexOf('{')) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query // Strip off the "{" and any leading WS q = q.Remove(0, 1).TrimStart(null); // Next item should be the source object if (-1 == (i = q.IndexOf('}'))) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query tempSourceObject = q.Substring(0, i).TrimEnd(null); q = q.Remove(0, i+1).TrimStart(null); // At this point we may or may not have a "where" clause if (0 < q.Length) { // Next should be the "where" clause if (0 != String.Compare (q, 0, tokenWhere, 0, tokenWhere.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"where"); // Invalid query q = q.Remove (0, tokenWhere.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace // Remaining tokens can appear in any order bool bResultClassFound = false; bool bAssocClassFound = false; bool bResultRoleFound = false; bool bRoleFound = false; bool bRequiredQualifierFound = false; bool bRequiredAssocQualifierFound = false; bool bClassDefsOnlyFound = false; bool bSchemaOnlyFound = false; // Keep looking for tokens until we are done while (true) { if ((q.Length >= tokenResultClass.Length) && (0 == String.Compare (q, 0, tokenResultClass, 0, tokenResultClass.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenResultClass, "=", ref bResultClassFound, ref tempRelatedClass); else if ((q.Length >= tokenAssocClass.Length) && (0 == String.Compare (q, 0, tokenAssocClass, 0, tokenAssocClass.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenAssocClass, "=", ref bAssocClassFound, ref tempRelationshipClass); else if ((q.Length >= tokenResultRole.Length) && (0 == String.Compare (q, 0, tokenResultRole, 0, tokenResultRole.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenResultRole, "=", ref bResultRoleFound, ref tempRelatedRole); else if ((q.Length >= tokenRole.Length) && (0 == String.Compare (q, 0, tokenRole, 0, tokenRole.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRole, "=", ref bRoleFound, ref tempThisRole); else if ((q.Length >= tokenRequiredQualifier.Length) && (0 == String.Compare (q, 0, tokenRequiredQualifier, 0, tokenRequiredQualifier.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRequiredQualifier, "=", ref bRequiredQualifierFound, ref tempRelatedQualifier); else if ((q.Length >= tokenRequiredAssocQualifier.Length) && (0 == String.Compare (q, 0, tokenRequiredAssocQualifier, 0, tokenRequiredAssocQualifier.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRequiredAssocQualifier, "=", ref bRequiredAssocQualifierFound, ref tempRelationshipQualifier); else if ((q.Length >= tokenSchemaOnly.Length) && (0 == String.Compare (q, 0, tokenSchemaOnly, 0, tokenSchemaOnly.Length, StringComparison.OrdinalIgnoreCase))) { ParseToken (ref q, tokenSchemaOnly, ref bSchemaOnlyFound); tempIsSchemaQuery = true; } else if ((q.Length >= tokenClassDefsOnly.Length) && (0 == String.Compare (q, 0, tokenClassDefsOnly, 0, tokenClassDefsOnly.Length, StringComparison.OrdinalIgnoreCase))) { ParseToken (ref q, tokenClassDefsOnly, ref bClassDefsOnlyFound); tempClassDefsOnly = true; } else if (0 == q.Length) break; // done else throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Unrecognized token } //Can't have both classDefsOnly and schemaOnly if (bSchemaOnlyFound && bClassDefsOnlyFound) throw new ArgumentException(RC.GetString("INVALID_QUERY")); } // Getting here means we parsed successfully. Assign the values. sourceObject = tempSourceObject; relatedClass = tempRelatedClass; relationshipClass = tempRelationshipClass; relatedRole = tempRelatedRole; thisRole = tempThisRole; relatedQualifier = tempRelatedQualifier; relationshipQualifier = tempRelationshipQualifier; classDefinitionsOnly = tempClassDefsOnly; isSchemaQuery = tempIsSchemaQuery; }//ParseQuery() //ICloneable ////// ///Creates a copy of the object. ////// The copied object. /// public override object Clone() { if (isSchemaQuery == false) return new RelatedObjectQuery(sourceObject, relatedClass, relationshipClass, relatedQualifier, relationshipQualifier, relatedRole, thisRole, classDefinitionsOnly); else return new RelatedObjectQuery(true, sourceObject, relatedClass, relationshipClass, relatedQualifier, relationshipQualifier, relatedRole, thisRole); } }//RelatedObjectQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WQL REFERENCES OF data query. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class RelationshipQuery : WqlObjectQuery { private static readonly string tokenReferences = "references"; private static readonly string tokenOf = "of"; private static readonly string tokenWhere = "where"; private static readonly string tokenResultClass = "resultclass"; private static readonly string tokenRole = "role"; private static readonly string tokenRequiredQualifier = "requiredqualifier"; private static readonly string tokenClassDefsOnly = "classdefsonly"; private static readonly string tokenSchemaOnly = "schemaonly"; private string sourceObject; private string relationshipClass; private string relationshipQualifier; private string thisRole; private bool classDefinitionsOnly; private bool isSchemaQuery; //default constructor ///The following example searches for all objects related to the /// 'C:' drive object: ///using System; /// using System.Management; /// /// class Sample_RelationshipQuery /// { /// public static int Main(string[] args) { /// RelationshipQuery query = /// new RelationshipQuery("references of {Win32_LogicalDisk.DeviceID='C:'}"); /// ManagementObjectSearcher searcher = /// new ManagementObjectSearcher(query); /// /// foreach (ManagementObject assoc in searcher.Get()) { /// Console.WriteLine("Association class = " + assoc["__CLASS"]); /// } /// /// return 0; /// } /// } ///
///Imports System /// Imports System.Management /// /// Class Sample_RelatedObjectQuery /// Overloads Public Shared Function Main(args() As String) As Integer /// Dim query As New RelationshipQuery("references of {Win32_LogicalDisk.DeviceID='C:'}") /// Dim searcher As New ManagementObjectSearcher(query) /// Dim assoc As ManagementObject /// /// For Each assoc In searcher.Get() /// Console.WriteLine("Association class = " & assoc("__CLASS")) /// Next assoc /// /// Return 0 /// End Function /// End Class ///
////// Initializes a new instance /// of the ///class. /// /// public RelationshipQuery() :this(null) {} //parameterized constructor //ISSUE : We have 2 possible constructors that take a single string : // one that takes the full query string and the other that takes the source object path. // We resolve this by trying to parse the string, if it succeeds we assume it's the query, if // not we assume it's the source object. ///Initializes a new instance of the ///class. This is the default constructor. /// /// The query string or the class name for this query. ///Initializes a new instance of the ///class. If the specified string can be succesfully parsed as /// a WQL query, it is considered to be the query string; otherwise, it is assumed to be the path of the source /// object for the query. In this case, the query is assumed to be an instances query. /// public RelationshipQuery(string queryOrSourceObject) { if (null != queryOrSourceObject) { // Minimally determine if the string is a query or instance name. // if (queryOrSourceObject.TrimStart().StartsWith(tokenReferences, StringComparison.OrdinalIgnoreCase)) { // Looks to be a query - do further checking. // QueryString = queryOrSourceObject; // Parse/validate; may throw. } else { // We'd like to treat it as the source object. Is it a valid // class or instance? // Do some basic sanity checking on whether it's a class/instance name // ManagementPath p = new ManagementPath (queryOrSourceObject); if ((p.IsClass || p.IsInstance) && (p.NamespacePath.Length==0)) { SourceObject = queryOrSourceObject; isSchemaQuery = false; } else throw new ArgumentException (RC.GetString("INVALID_QUERY"),"queryOrSourceObject"); } } } ///This example shows the two different ways to use this constructor: /////Full query string is specified to the constructor /// RelationshipQuery q = new RelationshipQuery("references of {Win32_ComputerSystem.Name='mymachine'}"); /// /// //Only the object of interest is specified to the constructor /// RelationshipQuery q = new RelationshipQuery("Win32_Service.Name='Alerter'"); ///
///'Full query string is specified to the constructor /// Dim q As New RelationshipQuery("references of {Win32_ComputerSystem.Name='mymachine'}") /// /// 'Only the object of interest is specified to the constructor /// Dim q As New RelationshipQuery("Win32_Service.Name='Alerter'") ///
////// /// The path of the source object for this query. /// The type of relationship for which to query. public RelationshipQuery(string sourceObject, string relationshipClass) : this(sourceObject, relationshipClass, null, null, false) {} //Do we need additional variants of constructors here ?? ///Initializes a new instance of the ///class for the given source object and relationship class. /// The query is assumed to be an instance query (as opposed to a schema query). /// /// The path of the source object for this query. /// The type of relationship for which to query. /// A qualifier required to be present on the relationship object. /// The role that the source object is required to play in the relationship. /// When this method returns, it contains a boolean that indicates that only class definitions for the resulting objects are returned. public RelationshipQuery(string sourceObject, string relationshipClass, string relationshipQualifier, string thisRole, bool classDefinitionsOnly) { this.isSchemaQuery = false; this.sourceObject = sourceObject; this.relationshipClass = relationshipClass; this.relationshipQualifier = relationshipQualifier; this.thisRole = thisRole; this.classDefinitionsOnly = classDefinitionsOnly; BuildQuery(); } ///Initializes a new instance of the ///class for the given set of parameters. /// The query is assumed to be an instance query (as opposed to a schema query). /// ///Initializes a new instance of the ///class for a schema query using the given set /// of parameters. This constructor is used for schema queries only, so the first /// parameter must be /// . to indicate that this is a schema query; otherwise, . /// The path of the source class for this query. /// The type of relationship for which to query. /// A qualifier required to be present on the relationship class. /// The role that the source class is required to play in the relationship. public RelationshipQuery(bool isSchemaQuery, string sourceObject, string relationshipClass, string relationshipQualifier, string thisRole) { if (isSchemaQuery == false) throw new ArgumentException(RC.GetString("INVALID_QUERY"), "isSchemaQuery"); this.isSchemaQuery = true; this.sourceObject = sourceObject; this.relationshipClass = relationshipClass; this.relationshipQualifier = relationshipQualifier; this.thisRole = thisRole; this.classDefinitionsOnly = false; //this parameter is not relevant for schema queries. BuildQuery(); } /// /// ///Gets or sets a value indicating whether this query is a schema query or an instance query. ////// ///if this query /// should be evaluated over the schema; if the query should /// be evaluated over instances. /// /// public bool IsSchemaQuery { get { return isSchemaQuery; } set { isSchemaQuery = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new query type. ////// ///Gets or sets the source object for this query. ////// A string representing the path of /// the object to be used for the query. /// ////// public string SourceObject { get { return (null != sourceObject) ? sourceObject : String.Empty; } set { sourceObject = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new source object. ////// ///Gets or sets the class of the relationship objects wanted in the query. ////// A string containing the relationship /// class name. /// ////// public string RelationshipClass { get { return (null != relationshipClass) ? relationshipClass : String.Empty; } set { relationshipClass = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new class. ////// ///Gets or sets a qualifier required on the relationship objects. ////// A string containing the name of the /// qualifier required on the relationship objects. /// ////// public string RelationshipQualifier { get { return (null != relationshipQualifier) ? relationshipQualifier : String.Empty; } set { relationshipQualifier = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new qualifier. ////// ///Gets or sets the role of the source object in the relationship. ////// A string containing the role of this /// object. /// ////// public string ThisRole { get { return (null != thisRole) ? thisRole : String.Empty; } set { thisRole = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any /// previous value stored in the object. The query string is /// rebuilt to reflect the new role. ////// ///Gets or sets a value indicating that only the class definitions of the relevant relationship objects be returned. ////// ////// if the query requests only class definitions of the /// result set; otherwise, . /// public bool ClassDefinitionsOnly { get { return classDefinitionsOnly; } set { classDefinitionsOnly = value; BuildQuery(); FireIdentifierChanged(); } } ///Setting this property value overrides any previous /// value stored in the object. As a side-effect, the query string is /// rebuilt to reflect the new flag. ////// Builds the query string according to the current property values. /// protected internal void BuildQuery() { //If the source object is not set we can't build a query //Shouldn't throw here because the user may be in the process of filling in the properties... if (sourceObject == null) SetQueryString(String.Empty); if ((sourceObject == null) || (sourceObject.Length==0)) return; //"references" clause string s = tokenReferences + " " + tokenOf + " {" + sourceObject + "}"; //If any of the other parameters are set we need a "where" clause if (!(RelationshipClass.Length==0) || !(RelationshipQualifier.Length==0) || !(ThisRole.Length==0) || classDefinitionsOnly || isSchemaQuery) { s = s + " " + tokenWhere; //"ResultClass" if (!(RelationshipClass.Length==0)) s = s + " " + tokenResultClass + " = " + relationshipClass; //"Role" if (!(ThisRole.Length==0)) s = s + " " + tokenRole + " = " + thisRole; //"RequiredQualifier" if (!(RelationshipQualifier.Length==0)) s = s + " " + tokenRequiredQualifier + " = " + relationshipQualifier; //"SchemaOnly" and "ClassDefsOnly" if (!isSchemaQuery) //this is an instance query - classDefs allowed { if (classDefinitionsOnly) s = s + " " + tokenClassDefsOnly; } else //this is a schema query, schemaonly required s = s + " " + tokenSchemaOnly; } //Set the queryString member to the built query (NB: note we set //by accessing the internal helper function rather than the property, //since we do not want to force a parse of a query we just built). SetQueryString (s); } //BuildQuery() ////// Parses the query string and sets the property values accordingly. /// /// The query string to be parsed. protected internal override void ParseQuery(string query) { // Temporary variables to hold token values until we are sure query is valid string tempSourceObject = null; string tempRelationshipClass = null; string tempThisRole = null; string tempRelationshipQualifier = null; bool tempClassDefsOnly = false; bool tempSchemaOnly = false; //Trim whitespaces string q = query.Trim(); int i; //Find "references" clause if (0 != String.Compare(q, 0, tokenReferences, 0, tokenReferences.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"references"); // Invalid query // Strip off the clause q = q.Remove(0, tokenReferences.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace // Next token should be "of" if (0 != String.Compare(q, 0, tokenOf, 0, tokenOf.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"of"); // Invalid query // Strip off the clause and leading WS q = q.Remove(0, tokenOf.Length).TrimStart (null); // Next character should be "{" if (0 != q.IndexOf('{')) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query // Strip off the "{" and any leading WS q = q.Remove(0, 1).TrimStart(null); // Next item should be the source object if (-1 == (i = q.IndexOf('}'))) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query tempSourceObject = q.Substring(0, i).TrimEnd(null); q = q.Remove(0, i+1).TrimStart(null); // At this point we may or may not have a "where" clause if (0 < q.Length) { // Next should be the "where" clause if (0 != String.Compare (q, 0, tokenWhere, 0, tokenWhere.Length, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(RC.GetString("INVALID_QUERY"),"where"); // Invalid query q = q.Remove (0, tokenWhere.Length); // Must be some white space next if ((0 == q.Length) || !Char.IsWhiteSpace (q[0])) throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Invalid query q = q.TrimStart(null); // Remove the leading whitespace // Remaining tokens can appear in any order bool bResultClassFound = false; bool bRoleFound = false; bool bRequiredQualifierFound = false; bool bClassDefsOnlyFound = false; bool bSchemaOnlyFound = false; // Keep looking for tokens until we are done while (true) { if ((q.Length >= tokenResultClass.Length) && (0 == String.Compare (q, 0, tokenResultClass, 0, tokenResultClass.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenResultClass, "=", ref bResultClassFound, ref tempRelationshipClass); else if ((q.Length >= tokenRole.Length) && (0 == String.Compare (q, 0, tokenRole, 0, tokenRole.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRole, "=", ref bRoleFound, ref tempThisRole); else if ((q.Length >= tokenRequiredQualifier.Length) && (0 == String.Compare (q, 0, tokenRequiredQualifier, 0, tokenRequiredQualifier.Length, StringComparison.OrdinalIgnoreCase))) ParseToken (ref q, tokenRequiredQualifier, "=", ref bRequiredQualifierFound, ref tempRelationshipQualifier); else if ((q.Length >= tokenClassDefsOnly.Length) && (0 == String.Compare (q, 0, tokenClassDefsOnly, 0, tokenClassDefsOnly.Length, StringComparison.OrdinalIgnoreCase))) { ParseToken (ref q, tokenClassDefsOnly, ref bClassDefsOnlyFound); tempClassDefsOnly = true; } else if ((q.Length >= tokenSchemaOnly.Length) && (0 == String.Compare (q, 0, tokenSchemaOnly, 0, tokenSchemaOnly.Length, StringComparison.OrdinalIgnoreCase))) { ParseToken (ref q, tokenSchemaOnly, ref bSchemaOnlyFound); tempSchemaOnly = true; } else if (0 == q.Length) break; // done else throw new ArgumentException(RC.GetString("INVALID_QUERY")); // Unrecognized token } //Can't have both classDefsOnly and schemaOnly if (tempClassDefsOnly && tempSchemaOnly) throw new ArgumentException(RC.GetString("INVALID_QUERY")); } // Getting here means we parsed successfully. Assign the values. sourceObject = tempSourceObject; relationshipClass = tempRelationshipClass; thisRole = tempThisRole; relationshipQualifier = tempRelationshipQualifier; classDefinitionsOnly = tempClassDefsOnly; isSchemaQuery = tempSchemaOnly; }//ParseQuery() //ICloneable ////// ///Creates a copy of the object. ////// The copied object. /// public override object Clone() { if (isSchemaQuery == false) return new RelationshipQuery(sourceObject, relationshipClass, relationshipQualifier, thisRole, classDefinitionsOnly); else return new RelationshipQuery(true, sourceObject, relationshipClass, relationshipQualifier, thisRole); } }//RelationshipQuery //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// ////// ///Represents a WMI event query in WQL format. ////// //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC// public class WqlEventQuery : EventQuery { private static readonly string tokenSelectAll = "select * "; private string eventClassName; private TimeSpan withinInterval; private string condition; private TimeSpan groupWithinInterval; private StringCollection groupByPropertyList; private string havingCondition; //default constructor ///using System; /// using System.Management; /// /// // This sample demonstrates how to subscribe to an event /// // using a WQL event query. /// /// class Sample_EventQuery /// { /// public static int Main(string[] args) /// { /// //For this example, we make sure we have an arbitrary class on root\default /// ManagementClass newClass = new ManagementClass( /// "root\\default", /// String.Empty, /// null); /// newClass["__Class"] = "TestWql"; /// newClass.Put(); /// /// //Create a query object for watching for class deletion events /// WqlEventQuery eventQuery = new WqlEventQuery("select * from __classdeletionevent"); /// /// //Initialize an event watcher object with this query /// ManagementEventWatcher watcher = new ManagementEventWatcher( /// new ManagementScope("root/default"), /// eventQuery); /// /// //Set up a handler for incoming events /// MyHandler handler = new MyHandler(); /// watcher.EventArrived += new EventArrivedEventHandler(handler.Arrived); /// /// //Start watching for events /// watcher.Start(); /// /// //For this example, we delete the class to trigger an event /// newClass.Delete(); /// /// //Nothing better to do - we loop to wait for an event to arrive. /// while (!handler.IsArrived) { /// System.Threading.Thread.Sleep(1000); /// } /// /// //In this example we only want to wait for one event, so we can stop watching /// watcher.Stop(); /// /// return 0; /// } /// /// public class MyHandler /// { /// private bool isArrived = false; /// /// //Handles the event when it arrives /// public void Arrived(object sender, EventArrivedEventArgs e) { /// ManagementBaseObject eventArg = (ManagementBaseObject)(e.NewEvent["TargetClass"]); /// Console.WriteLine("Class Deleted = " + eventArg["__CLASS"]); /// isArrived = true; /// } /// /// //Used to determine whether the event has arrived or not. /// public bool IsArrived { /// get { /// return isArrived; /// } /// } /// } /// } ///
///Imports System /// Imports System.Management /// /// ' This sample demonstrates how to subscribe an event /// ' using a WQL event query. /// /// Class Sample_EventQuery /// Public Shared Sub Main() /// /// 'For this example, we make sure we have an arbitrary class on root\default /// Dim newClass As New ManagementClass( _ /// "root\default", _ /// String.Empty, Nothing) /// newClass("__Class") = "TestWql" /// newClass.Put() /// /// 'Create a query object for watching for class deletion events /// Dim eventQuery As New WqlEventQuery("select * from __classdeletionevent") /// /// 'Initialize an event watcher object with this query /// Dim watcher As New ManagementEventWatcher( _ /// New ManagementScope("root/default"), _ /// eventQuery) /// /// 'Set up a handler for incoming events /// Dim handler As New MyHandler() /// AddHandler watcher.EventArrived, AddressOf handler.Arrived /// /// 'Start watching for events /// watcher.Start() /// /// 'For this example, we delete the class to trigger an event /// newClass.Delete() /// /// 'Nothing better to do - we loop to wait for an event to arrive. /// While Not handler.IsArrived /// Console.Write("0") /// System.Threading.Thread.Sleep(1000) /// End While /// /// 'In this example we only want to wait for one event, so we can stop watching /// watcher.Stop() /// /// End Sub /// /// Public Class MyHandler /// Private _isArrived As Boolean = False /// /// 'Handles the event when it arrives /// Public Sub Arrived(sender As Object, e As EventArrivedEventArgs) /// Dim eventArg As ManagementBaseObject = CType( _ /// e.NewEvent("TargetClass"), _ /// ManagementBaseObject) /// Console.WriteLine(("Class Deleted = " + eventArg("__CLASS"))) /// _isArrived = True /// End Sub /// /// 'Used to determine whether the event has arrived or not. /// Public ReadOnly Property IsArrived() As Boolean /// Get /// Return _isArrived /// End Get /// End Property /// End Class /// End Class ///
////// ///Initializes a new instance of the ///class. /// public WqlEventQuery() : this(null, TimeSpan.Zero, null, TimeSpan.Zero, null, null) {} //parameterized constructors //ISSUE : We have 2 possible constructors that take a single string : // one that takes the full query string and the other that takes the class name. // We resolve this by trying to parse the string, if it succeeds we assume it's the query, if // not we assume it's the class name. ///Initializes a new instance of the ////// class. This is the default /// constructor. /// /// The string representing either the entire event query or the name of the event class to query. The object will try to parse the string as a valid event query. If unsuccessful, the parser will assume that the parameter represents an event class name. ///Initializes a new instance of the ////// class based on the given /// query string or event class name. /// public WqlEventQuery(string queryOrEventClassName) { groupByPropertyList = new StringCollection(); if (null != queryOrEventClassName) { // Minimally determine if the string is a query or event class name. // if (queryOrEventClassName.TrimStart().StartsWith(tokenSelectAll, StringComparison.OrdinalIgnoreCase)) { QueryString = queryOrEventClassName; // Parse/validate; may throw. } else { // Do some basic sanity checking on whether it's a class name // ManagementPath p = new ManagementPath (queryOrEventClassName); if (p.IsClass && (p.NamespacePath.Length==0)) { EventClassName = queryOrEventClassName; } else throw new ArgumentException (RC.GetString("INVALID_QUERY"),"queryOrEventClassName"); } } } ///The two options below are equivalent : /////Full query string specified to the constructor /// WqlEventQuery q = new WqlEventQuery("SELECT * FROM MyEvent"); /// /// //Only relevant event class name specified to the constructor /// WqlEventQuery q = new WqlEventQuery("MyEvent"); //results in the same query as above. ///
///'Full query string specified to the constructor /// Dim q As New WqlEventQuery("SELECT * FROM MyEvent") /// /// 'Only relevant event class name specified to the constructor /// Dim q As New WqlEventQuery("MyEvent") 'results in the same query as above ///
////// /// The name of the event class to query. /// The condition to apply to events of the specified class. ///Initializes a new instance of the ////// class for the /// specified event class name, with the specified condition. /// public WqlEventQuery(string eventClassName, string condition) : this(eventClassName, TimeSpan.Zero, condition, TimeSpan.Zero, null, null) {} ///This example shows how to create an event query that contains a condition in /// addition to the event class : /////Requests all "MyEvent" events where the event's properties /// //match the specified condition /// WqlEventQuery q = new WqlEventQuery("MyEvent", "FirstProp < 20 and SecondProp = 'red'"); ///
///'Requests all "MyEvent" events where the event's properties /// 'match the specified condition /// Dim q As New WqlEventQuery("MyEvent", "FirstProp < 20 and SecondProp = 'red'") ///
////// /// The name of the event class to query. /// A timespan value specifying the latency acceptable for receiving this event. This value is used in cases where there is no explicit event provider for the query requested, and WMI is required to poll for the condition. This interval is the maximum amount of time that can pass before notification of an event must be delivered. ///Initializes a new instance of the ////// class for the specified /// event class, with the specified latency time. /// public WqlEventQuery(string eventClassName, TimeSpan withinInterval): this(eventClassName, withinInterval, null, TimeSpan.Zero, null, null) {} ///This example shows creating an event query that contains /// a /// time interval. /////Requests all instance creation events, with a specified latency of /// //10 seconds. The query created is "SELECT * FROM __InstanceCreationEvent WITHIN 10" /// WqlEventQuery q = new WqlEventQuery("__InstanceCreationEvent", /// new TimeSpan(0,0,10)); ///
///'Requests all instance creation events, with a specified latency of /// '10 seconds. The query created is "SELECT * FROM __InstanceCreationEvent WITHIN 10" /// Dim t As New TimeSpan(0,0,10) /// Dim q As New WqlEventQuery("__InstanceCreationEvent", t) ///
////// /// The name of the event class to query. /// A timespan value specifying the latency acceptable for receiving this event. This value is used in cases where there is no explicit event provider for the query requested and WMI is required to poll for the condition. This interval is the maximum amount of time that can pass before notification of an event must be delivered. /// The condition to apply to events of the specified class. ///Initializes a new instance of the ////// class with the specified /// event class name, polling interval, and condition. /// public WqlEventQuery(string eventClassName, TimeSpan withinInterval, string condition) : this(eventClassName, withinInterval, condition, TimeSpan.Zero, null, null) {} ///This example creates the event query: "SELECT * FROM /// ///WITHIN 10 WHERE /// ISA ", which means /// "send notification of the creation of /// instances, /// with a 10-second polling interval." //Requests notification of the creation of Win32_Service instances with a 10 second /// //allowed latency. /// WqlEventQuery q = new WqlEventQuery("__InstanceCreationEvent", /// new TimeSpan(0,0,10), /// "TargetInstance isa 'Win32_Service'"); ///
///'Requests notification of the creation of Win32_Service instances with a 10 second /// 'allowed latency. /// Dim t As New TimeSpan(0,0,10) /// Dim q As New WqlEventQuery("__InstanceCreationEvent", _ /// t, _ /// "TargetInstance isa ""Win32_Service""") ///
////// /// The name of the event class to query. /// The condition to apply to events of the specified class. /// The specified interval at which WMI sends one aggregate event, rather than many events. ///Initializes a new instance of the ////// class with the specified /// event class name, condition, and grouping interval. /// public WqlEventQuery(string eventClassName, string condition, TimeSpan groupWithinInterval) : this(eventClassName, TimeSpan.Zero, condition, groupWithinInterval, null, null) {} ///This example creates the event query: "SELECT * FROM /// ///WHERE = 5 /// GROUP WITHIN 10", which means "send notification of events of type /// , in which the /// is equal to 5, but send an aggregate event in /// a /// 10-second interval." //Sends an aggregate of the requested events every 10 seconds /// WqlEventQuery q = new WqlEventQuery("FrequentEvent", /// "InterestingProperty = 5", /// new TimeSpan(0,0,10)); ///
///'Sends an aggregate of the requested events every 10 seconds /// Dim t As New TimeSpan(0,0,10) /// Dim q As New WqlEventQuery("FrequentEvent", _ /// "InterestingProperty = 5", _ /// t) ///
////// /// The name of the event class to query. /// The condition to apply to events of the specified class. /// The specified interval at which WMI sends one aggregate event, rather than many events. /// The properties in the event class by which the events should be grouped. ///Initializes a new instance of the ////// class with the specified event class /// name, condition, grouping interval, and grouping properties. /// public WqlEventQuery(string eventClassName, string condition, TimeSpan groupWithinInterval, string[] groupByPropertyList) : this(eventClassName, TimeSpan.Zero, condition, groupWithinInterval, groupByPropertyList, null) {} ///This example creates the event query: "SELECT * FROM /// ///WHERE = 'MyBoss' GROUP /// WITHIN 300 BY ", which means "send notification when /// new email from a particular sender has arrived within the last 10 minutes, /// combined with other events that have the same value in the /// /// property." //Requests "EmailEvent" events where the Sender property is "MyBoss", and /// //groups them based on importance /// String[] props = {"Importance"}; /// WqlEventQuery q = new WqlEventQuery("EmailEvent", /// "Sender = 'MyBoss'", /// new TimeSpan(0,10,0), /// props); ///
///'Requests "EmailEvent" events where the Sender property is "MyBoss", and /// 'groups them based on importance /// Dim props() As String = {"Importance"} /// Dim t As New TimeSpan(0,10,0) /// Dim q As New WqlEventQuery("EmailEvent", _ /// "Sender = ""MyBoss""", _ /// t, _ /// props) ///
////// /// The name of the event class on which to be queried. /// A timespan value specifying the latency acceptable for receiving this event. This value is used in cases where there is no explicit event provider for the query requested, and WMI is required to poll for the condition. This interval is the maximum amount of time that can pass before notification of an event must be delivered. /// The condition to apply to events of the specified class. /// The specified interval at which WMI sends one aggregate event, rather than many events. /// The properties in the event class by which the events should be grouped. /// The condition to apply to the number of events. ///Initializes a new instance of the ////// class with the specified event class /// name, condition, grouping interval, grouping properties, and specified number of events. /// public WqlEventQuery(string eventClassName, TimeSpan withinInterval, string condition, TimeSpan groupWithinInterval, string[] groupByPropertyList, string havingCondition) { this.eventClassName = eventClassName; this.withinInterval = withinInterval; this.condition = condition; this.groupWithinInterval = groupWithinInterval; this.groupByPropertyList = new StringCollection (); if (null != groupByPropertyList) this.groupByPropertyList.AddRange (groupByPropertyList); this.havingCondition = havingCondition; BuildQuery(); } //QueryLanguage property is read-only in this class (does this work ??) ///This example creates the event query: "SELECT * FROM /// ///WHERE /// ISA GROUP WITHIN 300 BY /// HAVING /// > 15" which means "deliver aggregate events /// only if the number of events received from the /// same source exceeds 15." //Requests sending aggregated events if the number of events exceeds 15. /// String[] props = {"TargetInstance.SourceName"}; /// WqlEventQuery q = new WqlEventQuery("__InstanceCreationEvent", /// "TargetInstance isa 'Win32_NTLogEvent'", /// new TimeSpan(0,10,0), /// props, /// "NumberOfEvents >15"); ///
///'Requests sending aggregated events if the number of events exceeds 15. /// Dim props() As String = {"TargetInstance.SourceName"}; /// Dim t As New TimeSpan(0,10,0) /// Dim q As WqlEventQuery("__InstanceCreationEvent", _ /// "TargetInstance isa ""Win32_NTLogEvent""", _ /// t, _ /// props, _ /// "NumberOfEvents >15") ///
////// ///Gets or sets the language of the query. ////// public override string QueryLanguage { get {return base.QueryLanguage;} } ///The value of this property in this /// object is always "WQL". ////// ///Gets or sets the string representing the query. ////// A string representing the query. /// public override string QueryString { get { // We need to force a rebuild as we may not have detected // a change to selected properties BuildQuery (); return base.QueryString; } set { base.QueryString = value; } } ////// ///Gets or sets the event class to query. ////// A string containing the name of the /// event class to query. /// ////// ///Setting this property value overrides any previous value /// stored /// in the object. The query string is rebuilt to /// reflect the new class name. ////// public string EventClassName { get { return (null != eventClassName) ? eventClassName : String.Empty; } set { eventClassName = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM ". WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "MyEvent"; ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "MyEvent" ///
////// ///Gets or sets the condition to be applied to events of the /// specified class. ////// ///The condition is represented as a /// string, containing one or more clauses of the form: <propName> /// <operator> <value> combined with and/or operators. <propName> /// must represent a property defined on the event class specified in this query. ////// ///Setting this property value overrides any previous value /// stored in the object. The query string is rebuilt to /// reflect the new condition. ////// public string Condition { get { return (null != condition) ? condition : String.Empty; } set { condition = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM WHERE /// > 8". WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "MyEvent"; /// q.Condition = "PropVal > 8"; ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "MyEvent" /// q.Condition = "PropVal > 8" ///
////// ///Gets or sets the polling interval to be used in this query. ////// ///Null, if there is no polling involved; otherwise, a /// valid ////// value if polling is required. /// ///This property should only be set in cases /// where there is no event provider for the event requested, and WMI is required to /// poll for the requested condition. ///Setting this property value overrides any previous value /// stored in /// the object. The query string is rebuilt to reflect the new interval. ////// public TimeSpan WithinInterval { get { return withinInterval; } set { withinInterval = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM WITHIN 10 WHERE > 8". WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "__InstanceModificationEvent"; /// q.Condition = "PropVal > 8"; /// q.WithinInterval = new TimeSpan(0,0,10); ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "__InstanceModificationEvent" /// q.Condition = "PropVal > 8" /// q.WithinInterval = New TimeSpan(0,0,10) ///
////// ///Gets or sets the interval to be used for grouping events of /// the same type. ////// ///Null, if there is no /// grouping involved; otherwise, the interval in which WMI should group events of /// the same type. ////// ///Setting this property value overrides any previous value stored in /// the object. The query string is rebuilt to reflect the new interval. ////// public TimeSpan GroupWithinInterval { get { return groupWithinInterval; } set { groupWithinInterval = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM WHERE /// > 8 GROUP WITHIN 10", which means "send notification /// of all events where the /// property is greater than 8, and aggregate these events within 10-second intervals." WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "MyEvent"; /// q.Condition = "PropVal > 8"; /// q.GroupWithinInterval = new TimeSpan(0,0,10); ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "MyEvent" /// q.Condition = "PropVal > 8" /// q.GroupWithinInterval = New TimeSpan(0,0,10) ///
////// ///Gets or sets properties in the event to be used for /// grouping events of the same type. ////// ////// Null, if no grouping is required; otherwise, a collection of event /// property names. ////// ///Setting this property value overrides any previous value stored in /// the object. The query string is rebuilt to reflect the new grouping. ////// public StringCollection GroupByPropertyList { get { return groupByPropertyList; } set { // A tad painful since StringCollection doesn't support ICloneable StringCollection src = (StringCollection)value; StringCollection dst = new StringCollection (); foreach (String s in src) dst.Add (s); groupByPropertyList = dst; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM GROUP /// WITHIN 300 BY ", which means "send notification of all /// events, aggregated by the property, within 10-minute intervals." WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "EmailEvent"; /// q.GroupWithinInterval = new TimeSpan(0,10,0); /// q.GroupByPropertyList = new StringCollection(); /// q.GroupByPropertyList.Add("Sender"); ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "EmailEvent" /// q.GroupWithinInterval = New TimeSpan(0,10,0) /// q.GroupByPropertyList = New StringCollection() /// q.GroupByPropertyList.Add("Sender") ///
////// ///Gets or sets the condition to be applied to the aggregation of /// events, based on the number of events received. ////// ////// Null, if no aggregation or no condition should be applied; /// otherwise, a condition of the form "NumberOfEvents <operator> /// <value>". ////// ///Setting this property value overrides any previous value stored in /// the object. The query string is rebuilt to reflect the new grouping condition. ////// public string HavingCondition { get { return (null != havingCondition) ? havingCondition : String.Empty; } set { havingCondition = value; BuildQuery(); } } ///This example creates a new ////// that represents the query: "SELECT * FROM GROUP /// WITHIN 300 HAVING > 5", which means "send /// notification of all events, aggregated within /// 10-minute intervals, if there are more than 5 occurrences." WqlEventQuery q = new WqlEventQuery(); /// q.EventClassName = "EmailEvent"; /// q.GroupWithinInterval = new TimeSpan(0,10,0); /// q.HavingCondition = "NumberOfEvents > 5"; ///
///Dim q As New WqlEventQuery() /// q.EventClassName = "EmailEvent" /// q.GroupWithinInterval = new TimeSpan(0,10,0) /// q.HavingCondition = "NumberOfEvents > 5" ///
////// Builds the query string according to the current property values. /// protected internal void BuildQuery() { //If the event class name is not set we can't build a query //This shouldn't throw because the user may be in the process of setting properties... if ((eventClassName == null) || (eventClassName.Length==0)) { SetQueryString (String.Empty); return; } //Select clause string s = tokenSelectAll; //no property list allowed here... //From clause s = s + "from " + eventClassName; //Within clause if (withinInterval != TimeSpan.Zero) s = s + " within " + withinInterval.TotalSeconds.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Double))); //Where clause if (!(Condition.Length==0)) s = s + " where " + condition; //Group within clause if (groupWithinInterval != TimeSpan.Zero) { s = s + " group within " + groupWithinInterval.TotalSeconds.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Double))); //Group By clause if ((null != groupByPropertyList) && (0 < groupByPropertyList.Count)) { int count = groupByPropertyList.Count; s = s + " by "; for (int i=0; i= keyword.Length) && (0 == String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) { string intervalString = null; bFound = false; ParseToken(ref q, keyword, null, ref bFound, ref intervalString); withinInterval = TimeSpan.FromSeconds(((IConvertible)intervalString).ToDouble(null)); } //Find "group within" clause keyword = "group within "; if ((q.Length >= keyword.Length) && ((i = q.ToLower(CultureInfo.InvariantCulture).IndexOf(keyword, StringComparison.Ordinal)) != -1)) //found { //Separate the part of the string before this - that should be the "where" clause w = q.Substring(0, i).Trim(); q = q.Remove(0, i); string intervalString = null; bFound=false; ParseToken(ref q, keyword, null, ref bFound, ref intervalString); groupWithinInterval = TimeSpan.FromSeconds(((IConvertible)intervalString).ToDouble(null)); //Find "By" subclause keyword = "by "; if ((q.Length >= keyword.Length) && (0 == String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) { q = q.Remove(0, keyword.Length); if (null != groupByPropertyList) groupByPropertyList.Clear (); else groupByPropertyList = new StringCollection (); //get the property list while (true) { if ((i = q.IndexOf(',')) > 0) { tempProp = q.Substring(0, i); q = q.Remove(0, i+1).TrimStart(null); tempProp = tempProp.Trim(); if (tempProp.Length>0) groupByPropertyList.Add(tempProp); } else { //last property in the list if ((i = q.IndexOf(' ')) > 0) { tempProp = q.Substring(0, i); q = q.Remove(0, i).TrimStart(null); groupByPropertyList.Add(tempProp); break; } else //end of the query { groupByPropertyList.Add(q); return; } } } //while } //by //Find "Having" subclause keyword = "having "; bFound = false; if ((q.Length >= keyword.Length) && (0 == String.Compare (q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) { //the rest until the end is assumed to be the having condition q = q.Remove(0, keyword.Length); if (q.Length == 0) //bad query throw new ArgumentException(RC.GetString("INVALID_QUERY"),"having"); havingCondition = q; } } else //No "group within" then everything should be the "where" clause w = q.Trim(); //Find "where" clause keyword = "where "; if ((w.Length >= keyword.Length) && (0 == String.Compare (w, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) //where clause exists { condition = w.Substring(keyword.Length); } }//ParseQuery() //ICloneable /// /// ///Creates a copy of the object. ////// The copied object. /// public override object Clone() { string[] strArray = null; if (null != groupByPropertyList) { int count = groupByPropertyList.Count; if (0 < count) { strArray = new String [count]; groupByPropertyList.CopyTo (strArray, 0); } } return new WqlEventQuery(eventClassName, withinInterval, condition, groupWithinInterval, strArray, havingCondition); } }//WqlEventQuery ////// Converts a String to a ManagementQuery /// class ManagementQueryConverter : ExpandableObjectConverter { ////// Determines if this converter can convert an object in the given source type to the native type of the converter. /// /// An ITypeDescriptorContext that provides a format context. /// A Type that represents the type you wish to convert from. ////// public override Boolean CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if ((sourceType == typeof(ManagementQuery))) { return true; } return base.CanConvertFrom(context,sourceType); } ///true if this converter can perform the conversion; otherwise, false. ////// Gets a value indicating whether this converter can convert an object to the given destination type using the context. /// /// An ITypeDescriptorContext that provides a format context. /// A Type that represents the type you wish to convert to. ////// public override Boolean CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if ((destinationType == typeof(InstanceDescriptor))) { return true; } return base.CanConvertTo(context,destinationType); } ///true if this converter can perform the conversion; otherwise, false. ////// Converts the given object to another type. The most common types to convert /// are to and from a string object. The default implementation will make a call /// to ToString on the object if the object is valid and if the destination /// type is string. If this cannot convert to the desitnation type, this will /// throw a NotSupportedException. /// /// An ITypeDescriptorContext that provides a format context. /// A CultureInfo object. If a null reference (Nothing in Visual Basic) is passed, the current culture is assumed. /// The Object to convert. /// The Type to convert the value parameter to. ///An Object that represents the converted value. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == null) { throw new ArgumentNullException("destinationType"); } if (value is EventQuery && destinationType == typeof(InstanceDescriptor)) { EventQuery obj = ((EventQuery)(value)); ConstructorInfo ctor = typeof(EventQuery).GetConstructor(new Type[] {typeof(System.String)}); if (ctor != null) { return new InstanceDescriptor(ctor, new object[] {obj.QueryString}); } } if (value is ObjectQuery && destinationType == typeof(InstanceDescriptor)) { ObjectQuery obj = ((ObjectQuery)(value)); ConstructorInfo ctor = typeof(ObjectQuery).GetConstructor(new Type[] {typeof(System.String)}); if (ctor != null) { return new InstanceDescriptor(ctor, new object[] {obj.QueryString}); } } return base.ConvertTo(context,culture,value,destinationType); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MdiWindowListItemConverter.cs
- DesignerFrame.cs
- SqlUtil.cs
- SecurityContext.cs
- BindingMemberInfo.cs
- ToolTipAutomationPeer.cs
- ZipIOModeEnforcingStream.cs
- IdleTimeoutMonitor.cs
- StylusPointPropertyUnit.cs
- DesignTimeValidationFeature.cs
- AttributedMetaModel.cs
- GridViewPageEventArgs.cs
- ExpressionNormalizer.cs
- MetadataItem_Static.cs
- ComboBoxAutomationPeer.cs
- SizeF.cs
- SiteMapHierarchicalDataSourceView.cs
- WpfXamlMember.cs
- DataBindingHandlerAttribute.cs
- NumberFunctions.cs
- ClockController.cs
- PeerNameResolver.cs
- ToolZone.cs
- BasePropertyDescriptor.cs
- DataSourceGroupCollection.cs
- X509CertificateCollection.cs
- XmlIncludeAttribute.cs
- StandardCommands.cs
- SiteMapSection.cs
- WeakEventManager.cs
- HebrewNumber.cs
- ExceptionHandler.cs
- MouseBinding.cs
- MultiTargetingUtil.cs
- IISMapPath.cs
- Point3DValueSerializer.cs
- BaseDataListActionList.cs
- ViewgenGatekeeper.cs
- FixedSOMTableRow.cs
- AbstractDataSvcMapFileLoader.cs
- DataBindingExpressionBuilder.cs
- DesignSurfaceServiceContainer.cs
- KnownTypesHelper.cs
- ReflectPropertyDescriptor.cs
- ServiceInfo.cs
- EqualityComparer.cs
- CodeParameterDeclarationExpression.cs
- MediaElement.cs
- ProfilePropertySettings.cs
- IndexedEnumerable.cs
- DynamicArgumentDesigner.xaml.cs
- SimpleType.cs
- VarInfo.cs
- CodeCommentStatement.cs
- TabletDeviceInfo.cs
- WebPartConnectionsConfigureVerb.cs
- _SslState.cs
- LogPolicy.cs
- ConfigurationValue.cs
- SamlSubjectStatement.cs
- SetterBase.cs
- XMLDiffLoader.cs
- LingerOption.cs
- QueryRewriter.cs
- ObjectMaterializedEventArgs.cs
- Vector3DAnimationBase.cs
- PlainXmlDeserializer.cs
- QilIterator.cs
- EllipseGeometry.cs
- Parameter.cs
- AttributeAction.cs
- ObjectQuery_EntitySqlExtensions.cs
- ConfigurationSectionGroupCollection.cs
- XXXOnTypeBuilderInstantiation.cs
- TypeTypeConverter.cs
- QueryCacheKey.cs
- DeclarativeCatalogPart.cs
- WaitHandle.cs
- OrderToken.cs
- PermissionAttributes.cs
- CngKeyBlobFormat.cs
- XmlILOptimizerVisitor.cs
- FieldNameLookup.cs
- ExitEventArgs.cs
- SystemColors.cs
- BaseUriHelper.cs
- HuffCodec.cs
- StylusTip.cs
- _AcceptOverlappedAsyncResult.cs
- DocumentApplication.cs
- CodeEntryPointMethod.cs
- FixedFindEngine.cs
- UTF7Encoding.cs
- AccessText.cs
- TaskExtensions.cs
- KeySpline.cs
- ResizeGrip.cs
- Win32Exception.cs
- DocumentationServerProtocol.cs
- SingleKeyFrameCollection.cs