mirror of https://github.com/winsw/winsw
				
				
				
			
		
			
				
	
	
		
			220 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C#
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			220 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C#
		
	
	
		
			Executable File
		
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Text;
 | |
| using System.Reflection;
 | |
| using System.Management;
 | |
| using DynamicProxy;
 | |
| 
 | |
| namespace WMI
 | |
| {
 | |
|     //Reference: http://msdn2.microsoft.com/en-us/library/aa389390(VS.85).aspx
 | |
| 
 | |
|     public enum ReturnValue
 | |
|     {
 | |
|         Success = 0,
 | |
|         NotSupported = 1,
 | |
|         AccessDenied = 2,
 | |
|         DependentServicesRunning = 3,
 | |
|         InvalidServiceControl = 4,
 | |
|         ServiceCannotAcceptControl = 5,
 | |
|         ServiceNotActive = 6,
 | |
|         ServiceRequestTimeout = 7,
 | |
|         UnknownFailure = 8,
 | |
|         PathNotFound = 9,
 | |
|         ServiceAlreadyRunning = 10,
 | |
|         ServiceDatabaseLocked = 11,
 | |
|         ServiceDependencyDeleted = 12,
 | |
|         ServiceDependencyFailure = 13,
 | |
|         ServiceDisabled = 14,
 | |
|         ServiceLogonFailure = 15,
 | |
|         ServiceMarkedForDeletion = 16,
 | |
|         ServiceNoThread = 17,
 | |
|         StatusCircularDependency = 18,
 | |
|         StatusDuplicateName = 19,
 | |
|         StatusInvalidName = 20,
 | |
|         StatusInvalidParameter = 21,
 | |
|         StatusInvalidServiceAccount = 22,
 | |
|         StatusServiceExists = 23,
 | |
|         ServiceAlreadyPaused = 24,
 | |
| 
 | |
|         NoSuchService = 200
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Signals a problem in WMI related operations
 | |
|     /// </summary>
 | |
|     public class WmiException : Exception
 | |
|     {
 | |
|         public readonly ReturnValue ErrorCode;
 | |
| 
 | |
|         public WmiException(string msg, ReturnValue code)
 | |
|             : base(msg)
 | |
|         {
 | |
|             ErrorCode = code;
 | |
|         }
 | |
| 
 | |
|         public WmiException(ReturnValue code)
 | |
|             : this(code.ToString(), code)
 | |
|         {
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Associated a WMI class name to the proxy interface (which should extend from IWmiCollection)
 | |
|     /// </summary>
 | |
|     public class WmiClassName : Attribute
 | |
|     {
 | |
|         public readonly string Name;
 | |
|         public WmiClassName(string name) { this.Name = name; }
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Marker interface to denote a collection in WMI.
 | |
|     /// </summary>
 | |
|     public interface IWmiCollection {}
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Marker interface to denote an individual managed object
 | |
|     /// </summary>
 | |
|     public interface IWmiObject
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Reflect updates made to this object to the WMI provider.
 | |
|         /// </summary>
 | |
|         void Commit();
 | |
|     }
 | |
| 
 | |
|     public class WmiRoot
 | |
|     {
 | |
|         private readonly ManagementScope scope;
 | |
| 
 | |
|         public WmiRoot() : this(null) { }
 | |
| 
 | |
|         public WmiRoot(string machineName)
 | |
|         {
 | |
|             ConnectionOptions options = new ConnectionOptions();
 | |
|             options.EnablePrivileges = true;
 | |
|             options.Impersonation = ImpersonationLevel.Impersonate;
 | |
|             options.Authentication = AuthenticationLevel.PacketPrivacy;
 | |
| 
 | |
|             string path;
 | |
| 
 | |
|             if (machineName != null)
 | |
|                 path = String.Format(@"\\{0}\root\cimv2", machineName);
 | |
|             else
 | |
|                 path = @"\root\cimv2";
 | |
|             scope = new ManagementScope(path, options);
 | |
|             scope.Connect();
 | |
|         }
 | |
| 
 | |
|         private static string capitalize(string s)
 | |
|         {
 | |
|             return char.ToUpper(s[0]) + s.Substring(1);
 | |
|         }
 | |
| 
 | |
|         abstract class BaseHandler : IProxyInvocationHandler
 | |
|         {
 | |
|             public abstract object Invoke(object proxy, MethodInfo method, object[] args);
 | |
| 
 | |
|             protected void CheckError(ManagementBaseObject result)
 | |
|             {
 | |
|                 int code = Convert.ToInt32(result["returnValue"]);
 | |
|                 if (code != 0)
 | |
|                     throw new WmiException((ReturnValue)code);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         class InstanceHandler : BaseHandler, IWmiObject
 | |
|         {
 | |
|             private readonly ManagementObject mo;
 | |
| 
 | |
|             public InstanceHandler(ManagementObject o) { this.mo = o; }
 | |
| 
 | |
|             public override object Invoke(object proxy, MethodInfo method, object[] args)
 | |
|             {
 | |
|                 if (method.DeclaringType == typeof(IWmiObject))
 | |
|                 {
 | |
|                     return method.Invoke(this, args);
 | |
|                 }
 | |
| 
 | |
|                 // TODO: proper property support
 | |
|                 if (method.Name.StartsWith("set_"))
 | |
|                 {
 | |
|                     mo[method.Name.Substring(4)] = args[0];
 | |
|                     return null;
 | |
|                 }
 | |
|                 if (method.Name.StartsWith("get_"))
 | |
|                 {
 | |
|                     return mo[method.Name.Substring(4)];
 | |
|                 }
 | |
| 
 | |
|                 // method invocations
 | |
|                 ParameterInfo[] methodArgs = method.GetParameters();
 | |
| 
 | |
|                 ManagementBaseObject wmiArgs = mo.GetMethodParameters(method.Name);
 | |
|                 for (int i = 0; i < args.Length; i++)
 | |
|                     wmiArgs[capitalize(methodArgs[i].Name)] = args[i];
 | |
| 
 | |
|                 CheckError(mo.InvokeMethod(method.Name, wmiArgs, null));
 | |
|                 return null;
 | |
|             }
 | |
| 
 | |
|             public void Commit()
 | |
|             {
 | |
|                 mo.Put();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         class ClassHandler : BaseHandler
 | |
|         {
 | |
|             private readonly ManagementClass mc;
 | |
|             private readonly string wmiClass;
 | |
| 
 | |
|             public ClassHandler(ManagementClass mc, string wmiClass) { this.mc = mc; this.wmiClass = wmiClass; }
 | |
| 
 | |
|             public override object Invoke(object proxy, MethodInfo method, object[] args)
 | |
|             {
 | |
|                 ParameterInfo[] methodArgs = method.GetParameters();
 | |
| 
 | |
|                 if (method.Name.StartsWith("Select"))
 | |
|                 {
 | |
|                     // select method to find instances
 | |
|                     string query = "SELECT * FROM " + wmiClass + " WHERE ";
 | |
|                     for (int i = 0; i < args.Length; i++)
 | |
|                     {
 | |
|                         if (i != 0) query += " AND ";
 | |
|                         query += ' ' + capitalize(methodArgs[i].Name) + " = '" + args[i] + "'";
 | |
|                     }
 | |
| 
 | |
|                     ManagementObjectSearcher searcher = new ManagementObjectSearcher(mc.Scope, new ObjectQuery(query));
 | |
|                     ManagementObjectCollection results = searcher.Get();
 | |
|                     // TODO: support collections
 | |
|                     foreach (ManagementObject manObject in results)
 | |
|                         return ProxyFactory.GetInstance().Create(new InstanceHandler(manObject), method.ReturnType, true);
 | |
|                     return null;
 | |
|                 }
 | |
| 
 | |
|                 ManagementBaseObject wmiArgs = mc.GetMethodParameters(method.Name);
 | |
|                 for (int i = 0; i < args.Length; i++)
 | |
|                     wmiArgs[capitalize(methodArgs[i].Name)] = args[i];
 | |
| 
 | |
|                 CheckError(mc.InvokeMethod(method.Name, wmiArgs, null));
 | |
|                 return null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Obtains an object that corresponds to a table in WMI, which is a collection of a managed object.
 | |
|         /// </summary>
 | |
|         public T GetCollection<T>() where T : IWmiCollection
 | |
|         {
 | |
|             WmiClassName cn = (WmiClassName)typeof(T).GetCustomAttributes(typeof(WmiClassName), false)[0];
 | |
| 
 | |
|             ObjectGetOptions getOptions = new ObjectGetOptions();
 | |
|             ManagementPath path = new ManagementPath(cn.Name);
 | |
|             ManagementClass manClass = new ManagementClass(scope, path, getOptions);
 | |
|             return (T)ProxyFactory.GetInstance().Create(new ClassHandler(manClass, cn.Name), typeof(T), true);
 | |
|         }
 | |
|     }
 | |
| }
 |