using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Management;
namespace Vanara.Management
{
/// A dynamic object to handle WMI references.
///
///
public class DynamicMgmtObject : DynamicObject, IDisposable
{
private readonly ManagementObject obj;
/// Initializes a new instance of the class.
/// The object.
public DynamicMgmtObject(ManagementObject obj) => this.obj = obj ?? throw new ArgumentNullException();
/// Initializes a new instance of the class.
/// The scope.
/// The service name.
public DynamicMgmtObject(ManagementScope scope, string service)
{
if (!scope.IsConnected)
scope.Connect();
obj = scope.GetWMIService(service);
if (obj is null) throw new ArgumentNullException();
}
/// Initializes a new instance of the class.
/// The class.
public DynamicMgmtObject(ManagementClass wmiclass) => obj = wmiclass.CreateInstance();
/// Performs an implicit conversion from to .
/// The .
/// The result of the conversion.
public static implicit operator DynamicMgmtObject(ManagementObject mbo) => new(mbo);
///
public void Dispose() => ((IDisposable)obj).Dispose();
///
public override IEnumerable GetDynamicMemberNames() => obj.Properties.Cast().Select(d => d.Name);
///
public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.Type == typeof(ManagementObject))
{
result = obj;
return true;
}
return base.TryConvert(binder, out result);
}
///
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
try { result = obj.GetPropertyValue(binder.Name); return true; }
catch (ManagementException)
{
result = binder.Name switch
{
"ClassPath" or "ManagementClassPath" => obj.ClassPath,
"Path" or "ManagementPath" => obj.Path,
"Scope" or "ManagementScope" => obj.Scope,
_ => null
};
return result is not null;
}
}
///
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (args.Length == 1)
{
ManagementBaseObject input = null;
if (args[0] is ManagementBaseObject mbo)
{
input = mbo;
}
else if (args[0] is IDictionary eo)
{
input = obj.GetMethodParameters(binder.Name);
foreach (KeyValuePair kv in eo)
input[kv.Key] = kv.Value;
}
else if (args[0] is (string Key, object Value)[] a)
{
input = obj.GetMethodParameters(binder.Name);
foreach ((string Key, object Value) in a)
input[Key] = Value;
}
if (input is not null)
{
result = (DynamicMgmtObject)obj.InvokeMethod(binder.Name, input, null);
return true;
}
}
try
{
result = obj.InvokeMethod(binder.Name, args);
return true;
}
catch (ManagementException) { }
return base.TryInvokeMember(binder, args, out result);
}
///
public override bool TrySetMember(SetMemberBinder binder, object value)
{
try { obj.SetPropertyValue(binder.Name, value); return true; }
catch (ManagementException)
{
switch (binder.Name)
{
case "Path":
case "ManagementPath":
obj.Path = value as ManagementPath;
return true;
case "Scope":
case "ManagementScope":
obj.Scope = value as ManagementScope;
return true;
default:
return false;
}
}
}
}
}