mirror of https://github.com/winsw/winsw
				
				
				
			initial import
git-svn-id: https://svn.kenai.com/svn/winsw~subversion/trunk@2 c8b2a3fe-9b5b-6a51-a37e-dc31b0e308faremotes/git-svn
							parent
							
								
									08eed56c39
								
							
						
					
					
						commit
						e94628badf
					
				| 
						 | 
				
			
			@ -0,0 +1,348 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Reflection.Emit;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
 | 
			
		||||
namespace DynamicProxy
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Interface that a user defined proxy handler needs to implement.  This interface 
 | 
			
		||||
    /// defines one method that gets invoked by the generated proxy.  
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public interface IProxyInvocationHandler
 | 
			
		||||
    {
 | 
			
		||||
        /// <param name="proxy">The instance of the proxy</param>
 | 
			
		||||
        /// <param name="method">The method info that can be used to invoke the actual method on the object implementation</param>
 | 
			
		||||
        /// <param name="parameters">Parameters to pass to the method</param>
 | 
			
		||||
        /// <returns>Object</returns>
 | 
			
		||||
        object Invoke(object proxy, MethodInfo method, object[] parameters);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Factory class used to cache Types instances
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MetaDataFactory
 | 
			
		||||
    {
 | 
			
		||||
        private static Hashtable typeMap = new Hashtable();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Class constructor.  Private because this is a static class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private MetaDataFactory()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ///<summary>
 | 
			
		||||
        /// Method to add a new Type to the cache, using the type's fully qualified
 | 
			
		||||
        /// name as the key
 | 
			
		||||
        ///</summary>
 | 
			
		||||
        ///<param name="interfaceType">Type to cache</param>
 | 
			
		||||
        public static void Add(Type interfaceType)
 | 
			
		||||
        {
 | 
			
		||||
            if (interfaceType != null)
 | 
			
		||||
            {
 | 
			
		||||
                lock (typeMap.SyncRoot)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!typeMap.ContainsKey(interfaceType.FullName))
 | 
			
		||||
                    {
 | 
			
		||||
                        typeMap.Add(interfaceType.FullName, interfaceType);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ///<summary>
 | 
			
		||||
        /// Method to return the method of a given type at a specified index.
 | 
			
		||||
        ///</summary>
 | 
			
		||||
        ///<param name="name">Fully qualified name of the method to return</param>
 | 
			
		||||
        ///<param name="i">Index to use to return MethodInfo</param>
 | 
			
		||||
        ///<returns>MethodInfo</returns>
 | 
			
		||||
        public static MethodInfo GetMethod(string name, int i)
 | 
			
		||||
        {
 | 
			
		||||
            Type type = null;
 | 
			
		||||
            lock (typeMap.SyncRoot)
 | 
			
		||||
            {
 | 
			
		||||
                type = (Type)typeMap[name];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return type.GetMethods()[i];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static PropertyInfo GetProperty(string name, int i)
 | 
			
		||||
        {
 | 
			
		||||
            Type type = null;
 | 
			
		||||
            lock (typeMap.SyncRoot)
 | 
			
		||||
            {
 | 
			
		||||
                type = (Type)typeMap[name];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return type.GetProperties()[i];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ProxyFactory
 | 
			
		||||
    {
 | 
			
		||||
        private static ProxyFactory instance;
 | 
			
		||||
        private static Object lockObj = new Object();
 | 
			
		||||
 | 
			
		||||
        private Hashtable typeMap = Hashtable.Synchronized(new Hashtable());
 | 
			
		||||
        private static readonly Hashtable opCodeTypeMapper = new Hashtable();
 | 
			
		||||
 | 
			
		||||
        private const string PROXY_SUFFIX = "Proxy";
 | 
			
		||||
        private const string ASSEMBLY_NAME = "ProxyAssembly";
 | 
			
		||||
        private const string MODULE_NAME = "ProxyModule";
 | 
			
		||||
        private const string HANDLER_NAME = "handler";
 | 
			
		||||
 | 
			
		||||
        // Initialize the value type mapper.  This is needed for methods with intrinsic 
 | 
			
		||||
        // return types, used in the Emit process.
 | 
			
		||||
        static ProxyFactory()
 | 
			
		||||
        {
 | 
			
		||||
            opCodeTypeMapper.Add(typeof(System.Boolean), OpCodes.Ldind_I1);
 | 
			
		||||
            opCodeTypeMapper.Add(typeof(System.Int16), OpCodes.Ldind_I2);
 | 
			
		||||
            opCodeTypeMapper.Add(typeof(System.Int32), OpCodes.Ldind_I4);
 | 
			
		||||
            opCodeTypeMapper.Add(typeof(System.Int64), OpCodes.Ldind_I8);
 | 
			
		||||
            opCodeTypeMapper.Add(typeof(System.Double), OpCodes.Ldind_R8);
 | 
			
		||||
            opCodeTypeMapper.Add(typeof(System.Single), OpCodes.Ldind_R4);
 | 
			
		||||
            opCodeTypeMapper.Add(typeof(System.UInt16), OpCodes.Ldind_U2);
 | 
			
		||||
            opCodeTypeMapper.Add(typeof(System.UInt32), OpCodes.Ldind_U4);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ProxyFactory()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static ProxyFactory GetInstance()
 | 
			
		||||
        {
 | 
			
		||||
            if (instance == null)
 | 
			
		||||
            {
 | 
			
		||||
                CreateInstance();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return instance;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void CreateInstance()
 | 
			
		||||
        {
 | 
			
		||||
            lock (lockObj)
 | 
			
		||||
            {
 | 
			
		||||
                if (instance == null)
 | 
			
		||||
                {
 | 
			
		||||
                    instance = new ProxyFactory();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Object Create(IProxyInvocationHandler handler, Type objType, bool isObjInterface)
 | 
			
		||||
        {
 | 
			
		||||
            string typeName = objType.FullName + PROXY_SUFFIX;
 | 
			
		||||
            Type type = (Type)typeMap[typeName];
 | 
			
		||||
 | 
			
		||||
            // check to see if the type was in the cache.  If the type was not cached, then
 | 
			
		||||
            // create a new instance of the dynamic type and add it to the cache.
 | 
			
		||||
            if (type == null)
 | 
			
		||||
            {
 | 
			
		||||
                if (isObjInterface)
 | 
			
		||||
                {
 | 
			
		||||
                    type = CreateType(handler, new Type[] { objType }, typeName);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    type = CreateType(handler, objType.GetInterfaces(), typeName);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                typeMap.Add(typeName, type);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // return a new instance of the type.
 | 
			
		||||
            return Activator.CreateInstance(type, new object[] { handler });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Object Create(IProxyInvocationHandler handler, Type objType)
 | 
			
		||||
        {
 | 
			
		||||
            return Create(handler, objType, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Type CreateType(IProxyInvocationHandler handler, Type[] interfaces, string dynamicTypeName)
 | 
			
		||||
        {
 | 
			
		||||
            Type retVal = null;
 | 
			
		||||
 | 
			
		||||
            if (handler != null && interfaces != null)
 | 
			
		||||
            {
 | 
			
		||||
                Type objType = typeof(System.Object);
 | 
			
		||||
                Type handlerType = typeof(IProxyInvocationHandler);
 | 
			
		||||
 | 
			
		||||
                AppDomain domain = Thread.GetDomain();
 | 
			
		||||
                AssemblyName assemblyName = new AssemblyName();
 | 
			
		||||
                assemblyName.Name = ASSEMBLY_NAME;
 | 
			
		||||
                assemblyName.Version = new Version(1, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
                // create a new assembly for this proxy, one that isn't presisted on the file system
 | 
			
		||||
                AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(
 | 
			
		||||
                    assemblyName, AssemblyBuilderAccess.Run);
 | 
			
		||||
                    // assemblyName, AssemblyBuilderAccess.RunAndSave,".");  // to save it to the disk
 | 
			
		||||
 | 
			
		||||
                // create a new module for this proxy
 | 
			
		||||
                ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(MODULE_NAME);
 | 
			
		||||
 | 
			
		||||
                // Set the class to be public and sealed
 | 
			
		||||
                TypeAttributes typeAttributes =
 | 
			
		||||
                    TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed;
 | 
			
		||||
 | 
			
		||||
                // Gather up the proxy information and create a new type builder.  One that
 | 
			
		||||
                // inherits from Object and implements the interface passed in
 | 
			
		||||
                TypeBuilder typeBuilder = moduleBuilder.DefineType(
 | 
			
		||||
                    dynamicTypeName, typeAttributes, objType, interfaces);
 | 
			
		||||
 | 
			
		||||
                // Define a member variable to hold the delegate
 | 
			
		||||
                FieldBuilder handlerField = typeBuilder.DefineField(
 | 
			
		||||
                    HANDLER_NAME, handlerType, FieldAttributes.Private);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                // build a constructor that takes the delegate object as the only argument
 | 
			
		||||
                //ConstructorInfo defaultObjConstructor = objType.GetConstructor( new Type[0] );
 | 
			
		||||
                ConstructorInfo superConstructor = objType.GetConstructor(new Type[0]);
 | 
			
		||||
                ConstructorBuilder delegateConstructor = typeBuilder.DefineConstructor(
 | 
			
		||||
                    MethodAttributes.Public, CallingConventions.Standard, new Type[] { handlerType });
 | 
			
		||||
 | 
			
		||||
                #region( "Constructor IL Code" )
 | 
			
		||||
                ILGenerator constructorIL = delegateConstructor.GetILGenerator();
 | 
			
		||||
 | 
			
		||||
                // Load "this"
 | 
			
		||||
                constructorIL.Emit(OpCodes.Ldarg_0);
 | 
			
		||||
                // Load first constructor parameter
 | 
			
		||||
                constructorIL.Emit(OpCodes.Ldarg_1);
 | 
			
		||||
                // Set the first parameter into the handler field
 | 
			
		||||
                constructorIL.Emit(OpCodes.Stfld, handlerField);
 | 
			
		||||
                // Load "this"
 | 
			
		||||
                constructorIL.Emit(OpCodes.Ldarg_0);
 | 
			
		||||
                // Call the super constructor
 | 
			
		||||
                constructorIL.Emit(OpCodes.Call, superConstructor);
 | 
			
		||||
                // Constructor return
 | 
			
		||||
                constructorIL.Emit(OpCodes.Ret);
 | 
			
		||||
                #endregion
 | 
			
		||||
 | 
			
		||||
                // for every method that the interfaces define, build a corresponding 
 | 
			
		||||
                // method in the dynamic type that calls the handlers invoke method.  
 | 
			
		||||
                foreach (Type interfaceType in interfaces)
 | 
			
		||||
                {
 | 
			
		||||
                    GenerateMethod(interfaceType, handlerField, typeBuilder);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                retVal = typeBuilder.CreateType();
 | 
			
		||||
 | 
			
		||||
                // assemblyBuilder.Save(dynamicTypeName + ".dll");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return retVal;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static readonly MethodInfo INVOKE_METHOD = typeof(IProxyInvocationHandler).GetMethod("Invoke");
 | 
			
		||||
        private static readonly MethodInfo GET_METHODINFO_METHOD = typeof(MetaDataFactory).GetMethod("GetMethod", new Type[] { typeof(string), typeof(int) });
 | 
			
		||||
 | 
			
		||||
        private void GenerateMethod( Type interfaceType, FieldBuilder handlerField, TypeBuilder typeBuilder ) {
 | 
			
		||||
            MetaDataFactory.Add( interfaceType );
 | 
			
		||||
            MethodInfo[] interfaceMethods = interfaceType.GetMethods();
 | 
			
		||||
            PropertyInfo[] props = interfaceType.GetProperties();
 | 
			
		||||
 | 
			
		||||
            for ( int i = 0; i < interfaceMethods.Length; i++ ) {
 | 
			
		||||
                MethodInfo methodInfo = interfaceMethods[i];
 | 
			
		||||
 | 
			
		||||
                // Get the method parameters since we need to create an array
 | 
			
		||||
                // of parameter types
 | 
			
		||||
                ParameterInfo[] methodParams = methodInfo.GetParameters();
 | 
			
		||||
                int numOfParams = methodParams.Length;
 | 
			
		||||
                Type[] methodParameters = new Type[ numOfParams ];
 | 
			
		||||
 | 
			
		||||
                // convert the ParameterInfo objects into Type
 | 
			
		||||
                for ( int j = 0; j < numOfParams; j++ ) {
 | 
			
		||||
                    methodParameters[j] = methodParams[j].ParameterType;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // create a new builder for the method in the interface
 | 
			
		||||
                MethodBuilder methodBuilder = typeBuilder.DefineMethod(
 | 
			
		||||
                    methodInfo.Name, 
 | 
			
		||||
                    /*MethodAttributes.Public | MethodAttributes.Virtual | */ methodInfo.Attributes&~MethodAttributes.Abstract,
 | 
			
		||||
                    CallingConventions.Standard,
 | 
			
		||||
                    methodInfo.ReturnType, methodParameters );                                                   
 | 
			
		||||
 | 
			
		||||
                #region( "Handler Method IL Code" )
 | 
			
		||||
                ILGenerator methodIL = methodBuilder.GetILGenerator();
 | 
			
		||||
                        
 | 
			
		||||
                // load "this"
 | 
			
		||||
                methodIL.Emit( OpCodes.Ldarg_0 );
 | 
			
		||||
                // load the handler
 | 
			
		||||
                methodIL.Emit( OpCodes.Ldfld, handlerField );
 | 
			
		||||
                // load "this" since its needed for the call to invoke
 | 
			
		||||
                methodIL.Emit( OpCodes.Ldarg_0 );
 | 
			
		||||
                // load the name of the interface, used to get the MethodInfo object
 | 
			
		||||
                // from MetaDataFactory
 | 
			
		||||
                methodIL.Emit( OpCodes.Ldstr, interfaceType.FullName );
 | 
			
		||||
                // load the index, used to get the MethodInfo object 
 | 
			
		||||
                // from MetaDataFactory 
 | 
			
		||||
                methodIL.Emit( OpCodes.Ldc_I4, i ); 
 | 
			
		||||
                // invoke GetMethod in MetaDataFactory
 | 
			
		||||
                methodIL.Emit( OpCodes.Call, GET_METHODINFO_METHOD);
 | 
			
		||||
 | 
			
		||||
                // load the number of parameters onto the stack
 | 
			
		||||
                methodIL.Emit( OpCodes.Ldc_I4, numOfParams );
 | 
			
		||||
                // create a new array, using the size that was just pused on the stack
 | 
			
		||||
                methodIL.Emit( OpCodes.Newarr, typeof(object) );
 | 
			
		||||
                        
 | 
			
		||||
                // if we have any parameters, then iterate through and set the values
 | 
			
		||||
                // of each element to the corresponding arguments
 | 
			
		||||
                for ( int j = 0; j < numOfParams; j++ ) {
 | 
			
		||||
                    methodIL.Emit( OpCodes.Dup );   // this copies the array
 | 
			
		||||
                    methodIL.Emit( OpCodes.Ldc_I4, j );
 | 
			
		||||
                    methodIL.Emit( OpCodes.Ldarg, j + 1 );
 | 
			
		||||
                    if ( methodParameters[j].IsValueType ) {
 | 
			
		||||
                        methodIL.Emit( OpCodes.Box, methodParameters[j] );
 | 
			
		||||
                    }
 | 
			
		||||
                    methodIL.Emit( OpCodes.Stelem_Ref );                                    
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // call the Invoke method
 | 
			
		||||
                methodIL.Emit( OpCodes.Callvirt, INVOKE_METHOD );
 | 
			
		||||
                        
 | 
			
		||||
                if ( methodInfo.ReturnType != typeof(void) ) { 
 | 
			
		||||
                    // if the return type if a value type, then unbox the return value
 | 
			
		||||
                    // so that we don't get junk.
 | 
			
		||||
                    if ( methodInfo.ReturnType.IsValueType  ) {
 | 
			
		||||
                        methodIL.Emit( OpCodes.Unbox, methodInfo.ReturnType );
 | 
			
		||||
                        if ( methodInfo.ReturnType.IsEnum ) {
 | 
			
		||||
                            methodIL.Emit( OpCodes.Ldind_I4 );
 | 
			
		||||
                        } else if ( !methodInfo.ReturnType.IsPrimitive ) {
 | 
			
		||||
                            methodIL.Emit( OpCodes.Ldobj, methodInfo.ReturnType );
 | 
			
		||||
                        } else {
 | 
			
		||||
                            methodIL.Emit( (OpCode) opCodeTypeMapper[ methodInfo.ReturnType ] );
 | 
			
		||||
                        }
 | 
			
		||||
                    }                                                                     
 | 
			
		||||
                } else {
 | 
			
		||||
                    // pop the return value that Invoke returned from the stack since
 | 
			
		||||
                    // the method's return type is void. 
 | 
			
		||||
                    methodIL.Emit( OpCodes.Pop );
 | 
			
		||||
                }
 | 
			
		||||
                                            
 | 
			
		||||
                // Return
 | 
			
		||||
                methodIL.Emit( OpCodes.Ret );
 | 
			
		||||
                #endregion
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //for (int i = 0; i < props.Length; i++)
 | 
			
		||||
            //{
 | 
			
		||||
            //    PropertyInfo p = props[i];
 | 
			
		||||
 | 
			
		||||
            //    PropertyBuilder pb = typeBuilder.DefineProperty(p.Name, p.Attributes, p.PropertyType, new Type[] { p.PropertyType });
 | 
			
		||||
            //    pb.SetGetMethod((MethodBuilder)methodTable[p.GetGetMethod()]);
 | 
			
		||||
            //    pb.SetSetMethod((MethodBuilder)methodTable[p.GetSetMethod()]);
 | 
			
		||||
            //}
 | 
			
		||||
 | 
			
		||||
            // Iterate through the parent interfaces and recursively call this method
 | 
			
		||||
            foreach ( Type parentType in interfaceType.GetInterfaces() ) {
 | 
			
		||||
                GenerateMethod( parentType, handlerField, typeBuilder );            
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,335 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.ServiceProcess;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using WMI;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using Microsoft.Win32;
 | 
			
		||||
 | 
			
		||||
namespace winsw
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// In-memory representation of the configuration file.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ServiceDescriptor
 | 
			
		||||
    {
 | 
			
		||||
        private readonly XmlDocument dom = new XmlDocument();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Where did we find the configuration file?
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public readonly string BasePath;
 | 
			
		||||
 | 
			
		||||
        public static string ExecutablePath
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                // this returns the executable name as given by the calling process, so
 | 
			
		||||
                // it needs to be absolutized.
 | 
			
		||||
                string p = Environment.GetCommandLineArgs()[0];
 | 
			
		||||
                return Path.Combine(Environment.CurrentDirectory, p);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ServiceDescriptor()
 | 
			
		||||
        {
 | 
			
		||||
            // find co-located configuration xml. We search up to the ancestor directories to simplify debugging,
 | 
			
		||||
            // as well as trimming off ".vshost" suffix (which is used during debugging)
 | 
			
		||||
            string p = ExecutablePath;
 | 
			
		||||
            string baseName = Path.GetFileNameWithoutExtension(p);
 | 
			
		||||
            if (baseName.EndsWith(".vshost")) baseName = baseName.Substring(0, baseName.Length - 7);
 | 
			
		||||
            while (true)
 | 
			
		||||
            {
 | 
			
		||||
                p = Path.GetDirectoryName(p);
 | 
			
		||||
                if (File.Exists(Path.Combine(p, baseName + ".xml")))
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // register the base directory as environment variable so that future expansions can refer to this.
 | 
			
		||||
            Environment.SetEnvironmentVariable("BASE", p);
 | 
			
		||||
 | 
			
		||||
            BasePath = Path.Combine(p, baseName);
 | 
			
		||||
 | 
			
		||||
            dom.Load(BasePath+".xml");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string SingleElement(string tagName)
 | 
			
		||||
        {
 | 
			
		||||
            var n = dom.SelectSingleNode("//" + tagName);
 | 
			
		||||
            if (n == null) throw new InvalidDataException("<" + tagName + "> is missing in configuration XML");
 | 
			
		||||
            return Environment.ExpandEnvironmentVariables(n.InnerText);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Path to the executable.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string Executable
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleElement("executable");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Arguments
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string Arguments
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleElement("arguments");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Id
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleElement("id");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Caption
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleElement("name");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Description
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return SingleElement("description");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// True if the service can interact with the desktop.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Interactive
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return dom.SelectSingleNode("//interactive") != null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Environment variable overrides
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Dictionary<string, string> EnvironmentVariables
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                Dictionary<string, string> map = new Dictionary<string, string>();
 | 
			
		||||
                foreach (XmlNode n in dom.SelectNodes("//env"))
 | 
			
		||||
                {
 | 
			
		||||
                    map[n.Attributes["name"].Value] = Environment.ExpandEnvironmentVariables(n.Attributes["value"].Value);
 | 
			
		||||
                }
 | 
			
		||||
                return map;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class WrapperService : ServiceBase
 | 
			
		||||
    {
 | 
			
		||||
        private Process process = new Process();
 | 
			
		||||
        private ServiceDescriptor descriptor;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates to the watch dog thread that we are going to terminate the process,
 | 
			
		||||
        /// so don't try to kill us when the child exits.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private bool orderlyShutdown;
 | 
			
		||||
 | 
			
		||||
        public WrapperService()
 | 
			
		||||
        {
 | 
			
		||||
            this.descriptor = new ServiceDescriptor();
 | 
			
		||||
            this.ServiceName = descriptor.Id;
 | 
			
		||||
            this.CanStop = true;
 | 
			
		||||
            this.CanPauseAndContinue = false;
 | 
			
		||||
            this.AutoLog = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Copy stuff from StreamReader to StreamWriter
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private void CopyStream(StreamReader i, StreamWriter o)
 | 
			
		||||
        {
 | 
			
		||||
            char[] buf = new char[1024];
 | 
			
		||||
            while (true)
 | 
			
		||||
            {
 | 
			
		||||
                int sz = i.Read(buf, 0, buf.Length);
 | 
			
		||||
                if (sz == 0) break;
 | 
			
		||||
                o.Write(buf, 0, sz);
 | 
			
		||||
                o.Flush();
 | 
			
		||||
            }
 | 
			
		||||
            i.Close();
 | 
			
		||||
            o.Close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void OnStart(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            EventLog.WriteEntry("Starting "+descriptor.Executable+' '+descriptor.Arguments);
 | 
			
		||||
            string baseName = descriptor.BasePath;
 | 
			
		||||
 | 
			
		||||
            var ps = process.StartInfo;
 | 
			
		||||
            ps.FileName = descriptor.Executable;
 | 
			
		||||
            ps.Arguments = descriptor.Arguments;
 | 
			
		||||
            ps.CreateNoWindow = false;
 | 
			
		||||
            ps.UseShellExecute = false;
 | 
			
		||||
            ps.RedirectStandardInput = true; // this creates a pipe for stdin to the new process, instead of having it inherit our stdin.
 | 
			
		||||
            ps.RedirectStandardOutput = true;
 | 
			
		||||
            ps.RedirectStandardError = true;
 | 
			
		||||
 | 
			
		||||
            var envs = descriptor.EnvironmentVariables;
 | 
			
		||||
            foreach (string key in envs.Keys)
 | 
			
		||||
                ps.EnvironmentVariables[key] = envs[key];
 | 
			
		||||
 | 
			
		||||
            process.Start();
 | 
			
		||||
 | 
			
		||||
            // send stdout and stderr to its respective output file.
 | 
			
		||||
            new Thread(delegate() { CopyStream(process.StandardOutput, new StreamWriter(new FileStream(baseName + ".out.log", FileMode.Append))); }).Start();
 | 
			
		||||
            new Thread(delegate() { CopyStream(process.StandardError, new StreamWriter(new FileStream(baseName + ".err.log", FileMode.Append))); }).Start();
 | 
			
		||||
 | 
			
		||||
            // monitor the completion of the process
 | 
			
		||||
            new Thread(delegate()
 | 
			
		||||
            {
 | 
			
		||||
                process.WaitForExit();
 | 
			
		||||
                if (!orderlyShutdown)
 | 
			
		||||
                {
 | 
			
		||||
                    EventLog.WriteEntry("Child process terminated with " + process.ExitCode,EventLogEntryType.Warning);
 | 
			
		||||
                    Environment.Exit(process.ExitCode);
 | 
			
		||||
                }
 | 
			
		||||
            }).Start();
 | 
			
		||||
 | 
			
		||||
            process.StandardInput.Close(); // nothing for you to read!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void OnStop()
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                EventLog.WriteEntry("Stopping "+descriptor.Id);
 | 
			
		||||
                orderlyShutdown = true;
 | 
			
		||||
                process.Kill();
 | 
			
		||||
            }
 | 
			
		||||
            catch (InvalidOperationException)
 | 
			
		||||
            {
 | 
			
		||||
                // already terminated
 | 
			
		||||
            }
 | 
			
		||||
            process.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public static int Main(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                Run(args);
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
            catch (WmiException e)
 | 
			
		||||
            {
 | 
			
		||||
                Console.Error.WriteLine(e);
 | 
			
		||||
                return (int)e.ErrorCode;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                Console.Error.WriteLine(e);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void ThrowNoSuchService()
 | 
			
		||||
        {
 | 
			
		||||
            throw new WmiException(ReturnValue.NoSuchService);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void Run(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            if (args.Length > 0)
 | 
			
		||||
            {
 | 
			
		||||
                var d = new ServiceDescriptor();
 | 
			
		||||
                Win32Services svc = new WmiRoot().GetCollection<Win32Services>();
 | 
			
		||||
                Win32Service s = svc.Select(d.Id);
 | 
			
		||||
 | 
			
		||||
                args[0] = args[0].ToLower();
 | 
			
		||||
                if (args[0] == "install")
 | 
			
		||||
                {
 | 
			
		||||
                    svc.Create(
 | 
			
		||||
                        d.Id,
 | 
			
		||||
                        d.Caption,
 | 
			
		||||
                        ServiceDescriptor.ExecutablePath,
 | 
			
		||||
                        WMI.ServiceType.OwnProcess,
 | 
			
		||||
                        ErrorControl.UserNotified,
 | 
			
		||||
                        StartMode.Automatic,
 | 
			
		||||
                        d.Interactive);
 | 
			
		||||
                    // update the description
 | 
			
		||||
                    /* Somehow this doesn't work, even though it doesn't report an error
 | 
			
		||||
                    Win32Service s = svc.Select(d.Id);
 | 
			
		||||
                    s.Description = d.Description;
 | 
			
		||||
                    s.Commit();
 | 
			
		||||
                     */
 | 
			
		||||
 | 
			
		||||
                    // so using a classic method to set the description. Ugly.
 | 
			
		||||
                    Registry.LocalMachine.OpenSubKey("System").OpenSubKey("CurrentControlSet").OpenSubKey("Services")
 | 
			
		||||
                        .OpenSubKey(d.Id, true).SetValue("Description", d.Description);
 | 
			
		||||
                }
 | 
			
		||||
                if (args[0] == "uninstall")
 | 
			
		||||
                {
 | 
			
		||||
                    if (s == null)
 | 
			
		||||
                        return; // there's no such service, so consider it already uninstalled
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        s.Delete();
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (WmiException e)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (e.ErrorCode == ReturnValue.ServiceMarkedForDeletion)
 | 
			
		||||
                            return; // it's already uninstalled, so consider it a success
 | 
			
		||||
                        throw e;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (args[0] == "start")
 | 
			
		||||
                {
 | 
			
		||||
                    if (s == null) ThrowNoSuchService();
 | 
			
		||||
                    s.StartService();
 | 
			
		||||
                }
 | 
			
		||||
                if (args[0] == "stop")
 | 
			
		||||
                {
 | 
			
		||||
                    if (s == null) ThrowNoSuchService();
 | 
			
		||||
                    s.StopService();
 | 
			
		||||
                }
 | 
			
		||||
                if (args[0] == "status")
 | 
			
		||||
                {
 | 
			
		||||
                    if (s == null)
 | 
			
		||||
                        Console.WriteLine("NonExistent");
 | 
			
		||||
                    else if (s.Started)
 | 
			
		||||
                        Console.WriteLine("Started");
 | 
			
		||||
                    else
 | 
			
		||||
                        Console.WriteLine("Stopped");
 | 
			
		||||
                }
 | 
			
		||||
                if (args[0] == "test")
 | 
			
		||||
                {
 | 
			
		||||
                    WrapperService wsvc = new WrapperService();
 | 
			
		||||
                    wsvc.OnStart(args);
 | 
			
		||||
                    Thread.Sleep(1000);
 | 
			
		||||
                    wsvc.OnStop();
 | 
			
		||||
                }
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            ServiceBase.Run(new WrapperService());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
using System.Reflection;
 | 
			
		||||
using System.Runtime.CompilerServices;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
[assembly: AssemblyTitle("Windows Service Wrapper")]
 | 
			
		||||
[assembly: AssemblyDescription("Allows arbitrary process to run as a Windows service by wrapping it")]
 | 
			
		||||
[assembly: AssemblyConfiguration("")]
 | 
			
		||||
[assembly: AssemblyCompany("Sun Microsystems, Inc.")]
 | 
			
		||||
[assembly: AssemblyProduct("Windows Service Wrapper")]
 | 
			
		||||
[assembly: AssemblyCopyright("Copyright 2008 Sun Micorsystems, Inc.")]
 | 
			
		||||
[assembly: AssemblyTrademark("")]
 | 
			
		||||
[assembly: AssemblyCulture("")]
 | 
			
		||||
 | 
			
		||||
// Setting ComVisible to false makes the types in this assembly not visible 
 | 
			
		||||
// to COM components.  If you need to access a type in this assembly from 
 | 
			
		||||
// COM, set the ComVisible attribute to true on that type.
 | 
			
		||||
[assembly: ComVisible(false)]
 | 
			
		||||
 | 
			
		||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
 | 
			
		||||
[assembly: Guid("59ce18df-cacb-4360-bb80-798bd6459ca3")]
 | 
			
		||||
 | 
			
		||||
// Version information for an assembly consists of the following four values:
 | 
			
		||||
//
 | 
			
		||||
//      Major Version
 | 
			
		||||
//      Minor Version 
 | 
			
		||||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
// You can specify all the values or you can default the Build and Revision Numbers 
 | 
			
		||||
// by using the '*' as shown below:
 | 
			
		||||
// [assembly: AssemblyVersion("1.0.*")]
 | 
			
		||||
[assembly: AssemblyVersion("1.0.0.0")]
 | 
			
		||||
[assembly: AssemblyFileVersion("1.0.0.0")]
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,216 @@
 | 
			
		|||
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();
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
 | 
			
		||||
namespace WMI
 | 
			
		||||
{
 | 
			
		||||
    public enum ServiceType
 | 
			
		||||
    {
 | 
			
		||||
        KernalDriver = 1,
 | 
			
		||||
        FileSystemDriver = 2,
 | 
			
		||||
        Adapter = 4,
 | 
			
		||||
        RecognizerDriver = 8,
 | 
			
		||||
        OwnProcess = 16,
 | 
			
		||||
        ShareProcess = 32,
 | 
			
		||||
        InteractiveProcess = 256,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum ErrorControl
 | 
			
		||||
    {
 | 
			
		||||
        UserNotNotified = 0,
 | 
			
		||||
        UserNotified = 1,
 | 
			
		||||
        SystemRestartedWithLastKnownGoodConfiguration = 2,
 | 
			
		||||
        SystemAttemptsToStartWithAGoodConfiguration = 3
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum StartMode
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Device driver started by the operating system loader. This value is valid only for driver services.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Boot,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Device driver started by the operating system initialization process. This value is valid only for driver services.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        System,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Service to be started automatically by the Service Control Manager during system startup.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Automatic,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Service to be started by the Service Control Manager when a process calls the StartService method.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Manual,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Service that can no longer be started.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Disabled,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [WmiClassName("Win32_Service")]
 | 
			
		||||
    public interface Win32Services : IWmiCollection
 | 
			
		||||
    {
 | 
			
		||||
        // ReturnValue Create(bool desktopInteract, string displayName, int errorControl, string loadOrderGroup, string loadOrderGroupDependencies, string name, string pathName, string serviceDependencies, string serviceType, string startMode, string startName, string startPassword);
 | 
			
		||||
        void Create(string name, string displayName, string pathName, ServiceType serviceType, ErrorControl errorControl, StartMode startMode, bool desktopInteract);
 | 
			
		||||
 | 
			
		||||
        Win32Service Select(string name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface Win32Service : IWmiObject
 | 
			
		||||
    {
 | 
			
		||||
        string Description { get; set; }
 | 
			
		||||
        bool Started { get; }
 | 
			
		||||
        void Delete();
 | 
			
		||||
        void StartService();
 | 
			
		||||
        void StopService();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
<project xmlns="http://maven.apache.org/POM/4.0.0"
 | 
			
		||||
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 | 
			
		||||
  <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
  <groupId>com.sun.winsw</groupId>
 | 
			
		||||
  <artifactId>winsw</artifactId>
 | 
			
		||||
  <packaging>pom</packaging>
 | 
			
		||||
  <version>1.0</version>
 | 
			
		||||
  <name>Windows service wrapper</name>
 | 
			
		||||
    
 | 
			
		||||
   <distributionManagement>
 | 
			
		||||
    <repository>
 | 
			
		||||
      <id>java.net-m2-repository</id>
 | 
			
		||||
      <url>java-net:/maven2-repository/trunk/www/repository/</url>
 | 
			
		||||
    </repository>
 | 
			
		||||
  </distributionManagement>
 | 
			
		||||
 | 
			
		||||
  <build>
 | 
			
		||||
    <plugins>
 | 
			
		||||
      <!-- fake out maven and install the binary artifact -->
 | 
			
		||||
      <plugin>
 | 
			
		||||
        <groupId>org.jvnet.maven-antrun-extended-plugin</groupId>
 | 
			
		||||
        <artifactId>maven-antrun-extended-plugin</artifactId>
 | 
			
		||||
        <executions>
 | 
			
		||||
          <execution>
 | 
			
		||||
            <phase>package</phase>
 | 
			
		||||
            <goals>
 | 
			
		||||
              <goal>run</goal>
 | 
			
		||||
            </goals>
 | 
			
		||||
            <configuration>
 | 
			
		||||
              <tasks>
 | 
			
		||||
                <attachArtifact file="bin/Debug/winsw.exe" type="exe" classifier="bin" />
 | 
			
		||||
              </tasks>
 | 
			
		||||
            </configuration>
 | 
			
		||||
          </execution>
 | 
			
		||||
        </executions>
 | 
			
		||||
      </plugin>
 | 
			
		||||
    </plugins>
 | 
			
		||||
    <extensions>
 | 
			
		||||
      <extension>
 | 
			
		||||
        <groupId>org.jvnet.wagon-svn</groupId>
 | 
			
		||||
        <artifactId>wagon-svn</artifactId>
 | 
			
		||||
        <version>1.8</version>
 | 
			
		||||
      </extension>
 | 
			
		||||
    </extensions>
 | 
			
		||||
  </build>
 | 
			
		||||
  
 | 
			
		||||
  <repositories>
 | 
			
		||||
    <repository>
 | 
			
		||||
      <id>maven2-repository.dev.java.net</id>
 | 
			
		||||
      <name>Java.net Repository for Maven</name>
 | 
			
		||||
      <url>http://download.java.net/maven/2/</url>
 | 
			
		||||
    </repository>
 | 
			
		||||
  </repositories>
 | 
			
		||||
 | 
			
		||||
  <pluginRepositories>
 | 
			
		||||
    <pluginRepository>
 | 
			
		||||
      <id>maven2-repository.dev.java.net</id>
 | 
			
		||||
      <name>Java.net Repository for Maven</name>
 | 
			
		||||
      <url>http://download.java.net/maven/2/</url>
 | 
			
		||||
    </pluginRepository>
 | 
			
		||||
  </pluginRepositories>
 | 
			
		||||
</project>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
			
		||||
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
 | 
			
		||||
    <ProductVersion>9.0.21022</ProductVersion>
 | 
			
		||||
    <SchemaVersion>2.0</SchemaVersion>
 | 
			
		||||
    <ProjectGuid>{0DE77F55-ADE5-43C1-999A-0BC81153B039}</ProjectGuid>
 | 
			
		||||
    <OutputType>Exe</OutputType>
 | 
			
		||||
    <AppDesignerFolder>Properties</AppDesignerFolder>
 | 
			
		||||
    <RootNamespace>winsw</RootNamespace>
 | 
			
		||||
    <AssemblyName>winsw</AssemblyName>
 | 
			
		||||
    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
 | 
			
		||||
    <FileAlignment>512</FileAlignment>
 | 
			
		||||
    <StartupObject>
 | 
			
		||||
    </StartupObject>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <DebugSymbols>true</DebugSymbols>
 | 
			
		||||
    <DebugType>full</DebugType>
 | 
			
		||||
    <Optimize>false</Optimize>
 | 
			
		||||
    <OutputPath>bin\Debug\</OutputPath>
 | 
			
		||||
    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
 | 
			
		||||
    <DebugType>pdbonly</DebugType>
 | 
			
		||||
    <Optimize>true</Optimize>
 | 
			
		||||
    <OutputPath>bin\Release\</OutputPath>
 | 
			
		||||
    <DefineConstants>TRACE</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Reference Include="System" />
 | 
			
		||||
    <Reference Include="System.Management" />
 | 
			
		||||
    <Reference Include="System.Data" />
 | 
			
		||||
    <Reference Include="System.ServiceProcess" />
 | 
			
		||||
    <Reference Include="System.Xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="DynamicProxy.cs" />
 | 
			
		||||
    <Compile Include="Main.cs">
 | 
			
		||||
      <SubType>Component</SubType>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="Wmi.cs" />
 | 
			
		||||
    <Compile Include="WmiSchema.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Content Include="winsw.xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
			
		||||
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
 | 
			
		||||
       Other similar extension points exist, see Microsoft.Common.targets.
 | 
			
		||||
  <Target Name="BeforeBuild">
 | 
			
		||||
  </Target>
 | 
			
		||||
  <Target Name="AfterBuild">
 | 
			
		||||
  </Target>
 | 
			
		||||
  -->
 | 
			
		||||
</Project>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
 | 
			
		||||
Microsoft Visual Studio Solution File, Format Version 10.00
 | 
			
		||||
# Visual Studio 2008
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "winsw", "winsw.csproj", "{0DE77F55-ADE5-43C1-999A-0BC81153B039}"
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
		Debug|Any CPU = Debug|Any CPU
 | 
			
		||||
		Debug|Mixed Platforms = Debug|Mixed Platforms
 | 
			
		||||
		Debug|Win32 = Debug|Win32
 | 
			
		||||
		Release|Any CPU = Release|Any CPU
 | 
			
		||||
		Release|Mixed Platforms = Release|Mixed Platforms
 | 
			
		||||
		Release|Win32 = Release|Win32
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Win32.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 | 
			
		||||
		{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Win32.ActiveCfg = Release|Any CPU
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
EndGlobal
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
<configuration>
 | 
			
		||||
  <id>winsw</id>
 | 
			
		||||
  <name>Winsw test service(2)</name>
 | 
			
		||||
  <description>This service is a do-nothing test app. Really.</description>
 | 
			
		||||
  <executable>C:\development\jdk6u7\bin\java.exe</executable>
 | 
			
		||||
  <arguments>-classpath c:\cygwin\home\kohsuke\ws\hello-world\out\production\hello-world test.Main</arguments>
 | 
			
		||||
</configuration>
 | 
			
		||||
		Loading…
	
		Reference in New Issue