|
using System;
using System.Collections;
using System.Runtime.InteropServices;
using WbemClient_v1;
namespace System.Management
{
//CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
/// <summary>
/// <para> Represents the set of methods available in the collection.</para>
/// </summary>
/// <example>
/// <code lang='C#'>using System;
/// using System.Management;
///
/// // This sample demonstrates enumerate all methods in a ManagementClass object.
/// class Sample_MethodDataCollection
/// {
/// public static int Main(string[] args) {
/// ManagementClass diskClass = new ManagementClass("win32_logicaldisk");
/// MethodDataCollection diskMethods = diskClass.Methods;
/// foreach (MethodData method in diskMethods) {
/// Console.WriteLine("Method = " + method.Name);
/// }
/// return 0;
/// }
/// }
/// </code>
/// <code lang='VB'>Imports System
/// Imports System.Management
///
/// ' This sample demonstrates enumerate all methods in a ManagementClass object.
/// Class Sample_MethodDataCollection
/// Overloads Public Shared Function Main(args() As String) As Integer
/// Dim diskClass As New ManagementClass("win32_logicaldisk")
/// Dim diskMethods As MethodDataCollection = diskClass.Methods
/// Dim method As MethodData
/// For Each method In diskMethods
/// Console.WriteLine("Method = " & method.Name)
/// Next method
/// Return 0
/// End Function
/// End Class
/// </code>
/// </example>
//CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
public class MethodDataCollection : ICollection, IEnumerable
{
private ManagementObject parent;
private class enumLock
{
} //used to lock usage of BeginMethodEnum/NextMethod
internal MethodDataCollection(ManagementObject parent) : base()
{
this.parent = parent;
}
//
//ICollection
//
/// <summary>
/// <para>Represents the number of objects in the <see cref='System.Management.MethodDataCollection'/>.</para>
/// </summary>
/// <value>
/// <para> The number of objects in the <see cref='System.Management.MethodDataCollection'/>. </para>
/// </value>
public int Count
{
get
{
int i = 0;
IWbemClassObjectFreeThreaded inParameters = null, outParameters = null;
string methodName;
int status = (int)ManagementStatus.Failed;
lock(typeof(enumLock))
{
try
{
status = parent.wbemObject.BeginMethodEnumeration_(0);
if (status >= 0)
{
methodName = ""; // Condition primer to branch into the while loop.
while (methodName != null && status >= 0 && status != (int)tag_WBEMSTATUS.WBEM_S_NO_MORE_DATA)
{
methodName = null; inParameters = null; outParameters = null;
status = parent.wbemObject.NextMethod_(0, out methodName, out inParameters, out outParameters);
if (status >= 0 && status != (int)tag_WBEMSTATUS.WBEM_S_NO_MORE_DATA)
i++;
}
parent.wbemObject.EndMethodEnumeration_(); // Ignore status.
}
}
catch (COMException e)
{
ManagementException.ThrowWithExtendedInfo(e);
}
} // lock
if ((status & 0xfffff000) == 0x80041000)
{
ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
}
else if ((status & 0x80000000) != 0)
{
Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f());
}
return i;
}
}
/// <summary>
/// <para>Indicates whether the object is synchronized.</para>
/// </summary>
/// <value>
/// <para><see langword='true'/> if the object is synchronized;
/// otherwise, <see langword='false'/>.</para>
/// </value>
public bool IsSynchronized { get { return false; }
}
/// <summary>
/// <para>Represents the object to be used for synchronization.</para>
/// </summary>
/// <value>
/// <para>The object to be used for synchronization.</para>
/// </value>
public object SyncRoot { get { return this; }
}
/// <overload>
/// <para>Copies the <see cref='System.Management.MethodDataCollection'/> into an array.</para>
/// </overload>
/// <summary>
/// <para> Copies the <see cref='System.Management.MethodDataCollection'/> into an array.</para>
/// </summary>
/// <param name='array'>The array to which to copy the collection. </param>
/// <param name='index'>The index from which to start. </param>
public void CopyTo(Array array, int index)
{
//Use an enumerator to get the MethodData objects and attach them into the target array
foreach (MethodData m in this)
array.SetValue(m, index++);
}
/// <summary>
/// <para>Copies the <see cref='System.Management.MethodDataCollection'/> to a specialized <see cref='System.Management.MethodData'/>
/// array.</para>
/// </summary>
/// <param name='methodArray'>The destination array to which to copy the <see cref='System.Management.MethodData'/> objects.</param>
/// <param name=' index'>The index in the destination array from which to start the copy.</param>
public void CopyTo(MethodData[] methodArray, int index)
{
CopyTo((Array)methodArray, index);
}
//
// IEnumerable
//
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)(new MethodDataEnumerator(parent));
}
/// <summary>
/// <para>Returns an enumerator for the <see cref='System.Management.MethodDataCollection'/>.</para>
/// </summary>
/// <remarks>
/// <para> Each call to this method
/// returns a new enumerator on the collection. Multiple enumerators can be obtained
/// for the same method collection. However, each enumerator takes a snapshot
/// of the collection, so changes made to the collection after the enumerator was
/// obtained are not reflected.</para>
/// </remarks>
/// <returns>An <see cref="System.Collections.IEnumerator"/> to enumerate through the collection.</returns>
public MethodDataEnumerator GetEnumerator()
{
return new MethodDataEnumerator(parent);
}
//Enumerator class
/// <summary>
/// <para>Represents the enumerator for <see cref='System.Management.MethodData'/>
/// objects in the <see cref='System.Management.MethodDataCollection'/>.</para>
/// </summary>
/// <example>
/// <code lang='C#'>using System;
/// using System.Management;
///
/// // This sample demonstrates how to enumerate all methods in
/// // Win32_LogicalDisk class using MethodDataEnumerator object.
///
/// class Sample_MethodDataEnumerator
/// {
/// public static int Main(string[] args)
/// {
/// ManagementClass diskClass = new ManagementClass("win32_logicaldisk");
/// MethodDataCollection.MethodDataEnumerator diskEnumerator =
/// diskClass.Methods.GetEnumerator();
/// while(diskEnumerator.MoveNext())
/// {
/// MethodData method = diskEnumerator.Current;
/// Console.WriteLine("Method = " + method.Name);
/// }
/// return 0;
/// }
/// }
/// </code>
/// <code lang='VB'>Imports System
/// Imports System.Management
///
/// ' This sample demonstrates how to enumerate all methods in
/// ' Win32_LogicalDisk class using MethodDataEnumerator object.
///
/// Class Sample_MethodDataEnumerator
/// Overloads Public Shared Function Main(args() As String) As Integer
/// Dim diskClass As New ManagementClass("win32_logicaldisk")
/// Dim diskEnumerator As _
/// MethodDataCollection.MethodDataEnumerator = _
/// diskClass.Methods.GetEnumerator()
/// While diskEnumerator.MoveNext()
/// Dim method As MethodData = diskEnumerator.Current
/// Console.WriteLine("Method = " & method.Name)
/// End While
/// Return 0
/// End Function
/// End Class
/// </code>
/// </example>
public class MethodDataEnumerator : IEnumerator
{
private ManagementObject parent;
private ArrayList methodNames; //can't use simple array because we don't know the size...
private IEnumerator en;
//Internal constructor
//Because WMI doesn't provide a "GetMethodNames" for methods similar to "GetNames" for properties,
//We have to walk the methods list and cache the names here.
//We lock to ensure that another thread doesn't interfere in the Begin/Next sequence.
internal MethodDataEnumerator(ManagementObject parent)
{
this.parent = parent;
methodNames = new ArrayList();
IWbemClassObjectFreeThreaded inP = null, outP = null;
string tempMethodName;
int status = (int)ManagementStatus.Failed;
lock(typeof(enumLock))
{
try
{
status = parent.wbemObject.BeginMethodEnumeration_(0);
if (status >= 0)
{
tempMethodName = ""; // Condition primer to branch into the while loop.
while (tempMethodName != null && status >= 0 && status != (int)tag_WBEMSTATUS.WBEM_S_NO_MORE_DATA)
{
tempMethodName = null;
status = parent.wbemObject.NextMethod_(0, out tempMethodName, out inP, out outP);
if (status >= 0 && status != (int)tag_WBEMSTATUS.WBEM_S_NO_MORE_DATA)
methodNames.Add(tempMethodName);
}
parent.wbemObject.EndMethodEnumeration_(); // Ignore status.
}
}
catch (COMException e)
{
ManagementException.ThrowWithExtendedInfo(e);
}
en = methodNames.GetEnumerator();
}
if ((status & 0xfffff000) == 0x80041000)
{
ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
}
else if ((status & 0x80000000) != 0)
{
Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f());
}
}
/// <internalonly/>
object IEnumerator.Current { get { return (object)this.Current; } }
/// <summary>
/// <para>Returns the current <see cref='System.Management.MethodData'/> in the <see cref='System.Management.MethodDataCollection'/>
/// enumeration.</para>
/// </summary>
/// <value>The current <see cref='System.Management.MethodData'/> item in the collection.</value>
public MethodData Current
{
get
{
return new MethodData(parent, (string)en.Current);
}
}
/// <summary>
/// <para>Moves to the next element in the <see cref='System.Management.MethodDataCollection'/> enumeration.</para>
/// </summary>
/// <returns><see langword='true'/> if the enumerator was successfully advanced to the next method; <see langword='false'/> if the enumerator has passed the end of the collection.</returns>
public bool MoveNext ()
{
return en.MoveNext();
}
/// <summary>
/// <para>Resets the enumerator to the beginning of the <see cref='System.Management.MethodDataCollection'/> enumeration.</para>
/// </summary>
public void Reset()
{
en.Reset();
}
}//MethodDataEnumerator
//
//Methods
//
/// <summary>
/// <para>Returns the specified <see cref='System.Management.MethodData'/> from the <see cref='System.Management.MethodDataCollection'/>.</para>
/// </summary>
/// <param name='methodName'>The name of the method requested.</param>
/// <value>A <see cref='System.Management.MethodData'/> instance containing all information about the specified method.</value>
public virtual MethodData this[string methodName]
{
get
{
if (null == methodName)
throw new ArgumentNullException ("methodName");
return new MethodData(parent, methodName);
}
}
/// <summary>
/// <para>Removes a <see cref='System.Management.MethodData'/> from the <see cref='System.Management.MethodDataCollection'/>.</para>
/// </summary>
/// <param name='methodName'>The name of the method to remove from the collection.</param>
/// <remarks>
/// <para>
/// Removing <see cref='System.Management.MethodData'/> objects from the <see cref='System.Management.MethodDataCollection'/>
/// can only be done when the class has no
/// instances. Any other case will result in an exception.</para>
/// </remarks>
public virtual void Remove(string methodName)
{
if (parent.GetType() == typeof(ManagementObject)) //can't remove methods from instance
throw new InvalidOperationException();
int status = (int)ManagementStatus.Failed;
try
{
status = parent.wbemObject.DeleteMethod_(methodName);
}
catch (COMException e)
{
ManagementException.ThrowWithExtendedInfo(e);
}
if ((status & 0xfffff000) == 0x80041000)
{
ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
}
else if ((status & 0x80000000) != 0)
{
Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f());
}
}
//This variant takes only a method name and assumes a void method with no in/out parameters
/// <overload>
/// <para>Adds a <see cref='System.Management.MethodData'/> to the <see cref='System.Management.MethodDataCollection'/>.</para>
/// </overload>
/// <summary>
/// <para>Adds a <see cref='System.Management.MethodData'/> to the <see cref='System.Management.MethodDataCollection'/>. This overload will
/// add a new method with no parameters to the collection.</para>
/// </summary>
/// <param name='methodName'>The name of the method to add.</param>
/// <remarks>
/// <para> Adding <see cref='System.Management.MethodData'/> objects to the <see cref='System.Management.MethodDataCollection'/> can only
/// be done when the class has no instances. Any other case will result in an
/// exception.</para>
/// </remarks>
public virtual void Add(string methodName)
{
Add(methodName, null, null);
}
//This variant takes the full information, i.e. the method name and in & out param objects
/// <summary>
/// <para>Adds a <see cref='System.Management.MethodData'/> to the <see cref='System.Management.MethodDataCollection'/>. This overload will add a new method with the
/// specified parameter objects to the collection.</para>
/// </summary>
/// <param name='methodName'>The name of the method to add.</param>
/// <param name=' inParameters'>The <see cref='System.Management.ManagementBaseObject'/> holding the input parameters to the method.</param>
/// <param name=' outParameters'>The <see cref='System.Management.ManagementBaseObject'/> holding the output parameters to the method.</param>
/// <remarks>
/// <para> Adding <see cref='System.Management.MethodData'/> objects to the <see cref='System.Management.MethodDataCollection'/> can only be
/// done when the class has no instances. Any other case will result in an
/// exception.</para>
/// </remarks>
public virtual void Add(string methodName, ManagementBaseObject inParameters, ManagementBaseObject outParameters)
{
IWbemClassObjectFreeThreaded wbemIn = null, wbemOut = null;
if (parent.GetType() == typeof(ManagementObject)) //can't add methods to instance
throw new InvalidOperationException();
if (inParameters != null)
wbemIn = inParameters.wbemObject;
if (outParameters != null)
wbemOut = outParameters.wbemObject;
int status = (int)ManagementStatus.Failed;
try
{
status = parent.wbemObject.PutMethod_(methodName, 0, wbemIn, wbemOut);
}
catch (COMException e)
{
ManagementException.ThrowWithExtendedInfo(e);
}
if ((status & 0xfffff000) == 0x80041000)
{
ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
}
else if ((status & 0x80000000) != 0)
{
Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f());
}
}
}//MethodDataCollection
}
|