namespace Microsoft.VSDesigner.WMI { using System.Runtime.Serialization; using System; using System.Diagnostics; using System.Collections; using System.ComponentModel; using System.WinForms; using WbemScripting; using System.Management; // // // This represents the wmi class information for PB // // public class WMIObjectComponent : Component, ICustomTypeDescriptor { private void InitializeComponent () { } public enum WMISystemProperties { __CLASS = 0, __DYNASTY, __DERIVATION, __GENUS, __NAMESPACE, __RELPATH, __PATH, __SERVER, __SUPERCLASS, __PROPERTY_COUNT } const int NUM_OF_SYSTEM_PROPS = 10; //fields protected string CLASS = String.Empty; protected string DYNASTY = String.Empty; protected object[] DERIVATION = null; protected int GENUS = 0; protected string NAMESPACE = String.Empty; protected string RELPATH = String.Empty; protected string PATH = String.Empty; protected string SERVER = String.Empty; protected string SUPERCLASS = String.Empty; protected int PROPERTY_COUNT = 0; protected Dictionary SystemPropertyDictionary = null; protected ISWbemObject wmiObj = null; protected ISWbemObject wmiClassObj = null; protected ManagementObject mgmtObj = null; protected ManagementObject mgmtClassObj = null; private static MemberAttributeCollection emptyMemberAttrCollection = new MemberAttributeCollection(new MemberAttribute[0]); private static EventDescriptorCollection emptyEvtDescrCollection = new EventDescriptorCollection(new EventDescriptor[0]); private bool IsNewInstance = false; // // // Ctor from SWbemObject // // public WMIObjectComponent(ISWbemObject wbemObjIn, ISWbemObject wbemClassObjIn) { if (wbemObjIn == null) { throw (new ArgumentNullException("wbemObjIn")); } wmiObj = wbemObjIn; wmiClassObj = wbemClassObjIn; SystemPropertyDictionary = new Dictionary(NUM_OF_SYSTEM_PROPS); Initialize (); } /// /// note that Properties_ on ISWbemObject doesn't return system properties, /// so need to reconstruct them: __SERVER, __PATH, __GENUS are available through /// SWbemObjectPath; __DYNASTY, __DERIVATION can be accessed through SWbemObjct.Derivation_ /// private void Initialize() { try { ISWbemObjectPath path = (ISWbemObjectPath)wmiObj.Path_; if (path.IsClass) { GENUS = 1; } else //instance { GENUS = 2; } SystemPropertyDictionary.Add("__GENUS", GENUS); CLASS = path.Class; SystemPropertyDictionary.Add("__CLASS", CLASS); NAMESPACE = path.Namespace; SystemPropertyDictionary.Add("__NAMESPACE", NAMESPACE); PATH = path.Path; SystemPropertyDictionary.Add("__PATH", PATH); RELPATH = path.RelPath; SystemPropertyDictionary.Add("__RELPATH", RELPATH); SERVER = path.Server; SystemPropertyDictionary.Add("__SERVER", SERVER); //get PROPERTY_COUNT ISWbemPropertySet props = (ISWbemPropertySet) wmiObj.Properties_; IEnumerator eProps = ((IEnumerable)props).GetEnumerator(); while (eProps.MoveNext()) { PROPERTY_COUNT++; } SystemPropertyDictionary.Add("__PROPERTY_COUNT", PROPERTY_COUNT); //get inheritance-related properties Object[] oaDerivation = (Object[])wmiObj.Derivation_; if (oaDerivation.Length == 0) { DYNASTY = CLASS; } else { SUPERCLASS = oaDerivation[0].ToString(); DYNASTY = oaDerivation[oaDerivation.Length - 1].ToString(); } SystemPropertyDictionary.Add("__SUPERCLASS", SUPERCLASS); SystemPropertyDictionary.Add("__DYNASTY", DYNASTY); DERIVATION = new string[oaDerivation.Length]; Array.Copy(oaDerivation, DERIVATION, oaDerivation.Length); SystemPropertyDictionary.Add("__DERIVATION", DERIVATION); IsNewInstance = ((GENUS == 2) && (PATH == string.Empty)); } catch(Exception exc) { MessageBox.Show(WMISys.GetString("WMISE_Exception", exc.Message, exc.StackTrace)); } } /// /// Call when a transacted commit of properties is required (e.g., when saving a new instance) /// internal bool Commit() { try { /* wmiObj.Put_((int)WbemChangeFlagEnum.wbemChangeFlagCreateOrUpdate | (int)WbemFlagEnum.wbemFlagUseAmendedQualifiers, null); */ PutOptions putOpts = new PutOptions(null, true, //use amended qualifiers PutType.UpdateOrCreate); mgmtObj.Put(putOpts); return true; } catch (Exception exc) { MessageBox.Show(WMISys.GetString("WMISE_ObjComp_PutFailed", PATH, exc.Message)); return false; } } /// /// Retrieves an array of member attributes for the given object. /// /// /// the array of attributes on the class. /// MemberAttributeCollection ICustomTypeDescriptor.GetAttributes() { return emptyMemberAttrCollection; //TODO: return qualifiers here??? } /// /// Retrieves the class name for this object. If null is returned, /// the type name is used. /// /// /// The class name for the object, or null if the default will be used. /// string ICustomTypeDescriptor.GetClassName() { return CLASS; } /// /// Retrieves the name for this object. If null is returned, /// the default is used. /// /// /// The name for the object, or null if the default will be used. /// string ICustomTypeDescriptor.GetComponentName() { return null; } /// /// Retrieves the type converter for this object. /// /// /// A TypeConverter. If null is returned, the default is used. /// TypeConverter ICustomTypeDescriptor.GetConverter() { return null; } /// /// Retrieves the default event. /// /// /// the default event, or null if there are no /// events /// EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return null; } /// /// Retrieves the default property. /// /// /// the default property, or null if there are no /// properties /// PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { //returns first property ISWbemPropertySet props = (ISWbemPropertySet) wmiObj.Properties_; IEnumerator eProps = ((IEnumerable)props).GetEnumerator(); eProps.MoveNext(); if (eProps.Current == null) { return null; } String defPropName = ((ISWbemProperty)eProps.Current).Name; return new WMIPropertyDescriptor(mgmtObj, mgmtClassObj, wmiObj, wmiClassObj, defPropName, !IsNewInstance); } /// /// Retrieves the an editor for this object. /// /// /// An editor of the requested type, or null. /// object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return null; } /// /// Retrieves an array of events that the given component instance /// provides. This may differ from the set of events the class /// provides. If the component is sited, the site may add or remove /// additional events. /// /// /// an array of events this component surfaces. /// EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return emptyEvtDescrCollection; } /// /// Retrieves an array of events that the given component instance /// provides. This may differ from the set of events the class /// provides. If the component is sited, the site may add or remove /// additional events. The returned array of events will be /// filtered by the given set of attributes. /// /// /// A set of attributes to use as a filter. /// /// If a MemberAttribute instance is specified and /// the event does not have an instance of that attribute's /// class, this will still include the event if the /// MemberAttribute is the same as it's Default property. /// /// /// an array of events this component surfaces that match /// the given set of attributes.. /// EventDescriptorCollection ICustomTypeDescriptor.GetEvents(MemberAttribute[] attributes) { return emptyEvtDescrCollection; } /// /// Retrieves an array of properties that the given component instance /// provides. This may differ from the set of properties the class /// provides. If the component is sited, the site may add or remove /// additional properties. /// /// /// an array of properties this component surfaces. /// PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { //NOTE: this re-initializing of mgmtObj and mgmtClassObj is a workaround: //apparently, the cached pointers that were created on a different thread //don't work: Interop marshalling problems? mgmtObj = null; mgmtObj = new ManagementObject(wmiObj.Path_.Path); mgmtClassObj = null; mgmtClassObj = new ManagementObject(wmiClassObj.Path_.Path); ISWbemPropertySet props = (ISWbemPropertySet) wmiObj.Properties_; IEnumerator eProps = ((IEnumerable)props).GetEnumerator(); PropertyDescriptor[] propDescrArray = new PropertyDescriptor[((ISWbemPropertySet)props).Count + NUM_OF_SYSTEM_PROPS]; if (propDescrArray.Length != 0) { int counter = 0; while (eProps.MoveNext()) { ISWbemProperty curProp = (ISWbemProperty)eProps.Current; if (GENUS== 2) { //get the property on the class object: to get to "Values" qualifier curProp = wmiClassObj.Properties_.Item(curProp.Name, 0); } /* if (WmiHelper.IsValueMap(curProp)) { //MessageBox.Show("Value map property " + ((ISWbemProperty)eProps.Current).Name); propDescrArray[counter++] = new WMIEnumPropertyDescriptor(mgmtObj, mgmtClassObj, wmiObj, wmiClassObj, curProp.Name, !IsNewInstance); } else */ { propDescrArray[counter++] = new WMIPropertyDescriptor( mgmtObj, mgmtClassObj, wmiObj, wmiClassObj, curProp.Name, !IsNewInstance); } } //add system properties IDictionaryEnumerator enumSys = (IDictionaryEnumerator)((IEnumerable)SystemPropertyDictionary).GetEnumerator(); while (enumSys.MoveNext()) { propDescrArray[counter++] = new WMISystemPropertyDescriptor(wmiObj, enumSys.Key.ToString(), enumSys.Value); } } return (new PropertyDescriptorCollection (propDescrArray )); } /// /// Retrieves an array of properties that the given component instance /// provides. This may differ from the set of properties the class /// provides. If the component is sited, the site may add or remove /// additional properties. The returned array of properties will be /// filtered by the given set of attributes. /// /// /// A set of attributes to use as a filter. /// /// If a MemberAttribute instance is specified and /// the property does not have an instance of that attribute's /// class, this will still include the property if the /// MemberAttribute is the same as it's Default property. /// /// /// an array of properties this component surfaces that match /// the given set of attributes.. /// PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(MemberAttribute[] attributes) { return ((ICustomTypeDescriptor)this).GetProperties(); } /// /// Retrieves the object that directly depends on this value being edited. This is /// generally the object that is required for the PropertyDescriptor's GetValue and SetValue /// methods. If 'null' is passed for the PropertyDescriptor, the ICustomComponent /// descripotor implemementation should return the default object, that is the main /// object that exposes the properties and attributes, /// /// /// The PropertyDescriptor to find the owner for. This call should return an object /// such that the call "pd.GetValue(GetPropertyOwner(pd));" will generally succeed. /// If 'null' is passed for pd, the main object that owns the properties and attributes /// should be returned. /// /// /// valueOwner /// object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { return this; } } }