/// <summary>
        /// Determine whether the specified service is configured to trigger start
        /// </summary>
        /// <param name="hService">
        /// A handle to the service. This handle is returned by the OpenService or
        /// CreateService function and must have the SERVICE_QUERY_CONFIG access right.
        /// </param>
        /// <returns></returns>
        public static bool IsTriggerStartService(SafeServiceHandle hService)
        {
            // Query the service trigger info size of the current serivce
            int cbBytesNeeded = -1;

            NativeMethods.QueryServiceConfig2(hService,
                                              ServiceConfig2InfoLevel.SERVICE_CONFIG_TRIGGER_INFO, IntPtr.Zero, 0,
                                              out cbBytesNeeded);
            if (cbBytesNeeded == -1)
            {
                // If failed, get the last Win32 error and throw a Win32Exception
                throw new Win32Exception();
            }

            // Allocate memory for the service trigger info struct
            IntPtr pBuffer = Marshal.AllocHGlobal(cbBytesNeeded);

            try
            {
                // Retrieve the service trigger info

                if (!NativeMethods.QueryServiceConfig2(hService,
                                                       ServiceConfig2InfoLevel.SERVICE_CONFIG_TRIGGER_INFO, pBuffer,
                                                       cbBytesNeeded, out cbBytesNeeded))
                {
                    // If failed, get the last Win32 error and throw a Win32Exception
                    throw new Win32Exception();
                }

                SERVICE_TRIGGER_INFO sti = (SERVICE_TRIGGER_INFO)
                                           Marshal.PtrToStructure(pBuffer, typeof(SERVICE_TRIGGER_INFO));

                // You can also retrieve more trigger information of the service

                //for (int i = 0; i < sti.cTriggers; i++)
                //{
                //    // Calculate the address of the SERVICE_TRIGGER struct
                //    IntPtr pst = new IntPtr((long)sti.pTriggers +
                //        i * Marshal.SizeOf(typeof(SERVICE_TRIGGER)));

                //    // Marshal the native SERVICE_TRIGGER struct to .NET struct
                //    SERVICE_TRIGGER st = (SERVICE_TRIGGER)Marshal.PtrToStructure(pst,
                //        typeof(SERVICE_TRIGGER));
                //
                //    // Get more information from the SERVICE_TRIGGER struct
                //    // ...
                //}

                return(sti.cTriggers > 0);
            }
            finally
            {
                // Free the memory of the service trigger info struct
                if (pBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pBuffer);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Determine if the current service is trigger-start
        /// </summary>
        /// <returns></returns>
        protected bool IsTriggerStartService()
        {
            using (ServiceController sc = new ServiceController(this.ServiceName))
            {
                // Query the service trigger info size of the current serivce
                int cbBytesNeeded = -1, errorCode = 0;
                ServiceNative.QueryServiceConfig2(sc.ServiceHandle.DangerousGetHandle(),
                                                  ServiceConfig2InfoLevel.SERVICE_CONFIG_TRIGGER_INFO,
                                                  IntPtr.Zero, 0, out cbBytesNeeded);
                if (cbBytesNeeded == -1)
                {
                    // If failed, throw the error information
                    errorCode = Marshal.GetLastWin32Error();
                    throw Marshal.GetExceptionForHR(errorCode);
                }

                // Allocate memory for the service trigger info struct
                IntPtr pBuffer = Marshal.AllocHGlobal(cbBytesNeeded);

                // Retrieve the service trigger info
                bool bSuccess = ServiceNative.QueryServiceConfig2(
                    sc.ServiceHandle.DangerousGetHandle(),
                    ServiceConfig2InfoLevel.SERVICE_CONFIG_TRIGGER_INFO,
                    pBuffer, cbBytesNeeded, out cbBytesNeeded) != 0;
                if (!bSuccess)
                {
                    // If failed, clean up the memory and throw the error
                    Marshal.FreeHGlobal(pBuffer);
                    errorCode = Marshal.GetLastWin32Error();
                    throw Marshal.GetExceptionForHR(errorCode);
                }

                // Determine if the serivce is trigger-start
                SERVICE_TRIGGER_INFO serviceTriggerInfo = (SERVICE_TRIGGER_INFO)
                                                          Marshal.PtrToStructure(pBuffer, typeof(SERVICE_TRIGGER_INFO));
                bool bTriggerStart = serviceTriggerInfo.cTriggers > 0;

                Marshal.FreeHGlobal(pBuffer);

                return(bTriggerStart);
            }
        }
        /// <summary>
        /// Set the service to trigger-start when the first IP address on the TCP/IP
        /// networking stack becomes available, and trigger-stop when the last IP
        /// address on the TCP/IP networking stack becomes unavailable.
        /// </summary>
        /// <param name="hService">
        /// A handle to the service. This handle is returned by the OpenService or
        /// CreateService function and must have the SERVICE_CHANGE_CONFIG access right.
        /// </param>
        public static void SetServiceTriggerStartOnIPAddressArrival(SafeServiceHandle hService)
        {
            IntPtr pGuidIpAddressArrival = IntPtr.Zero;
            IntPtr pGuidIpAddressRemoval = IntPtr.Zero;
            IntPtr pServiceTriggers      = IntPtr.Zero;
            IntPtr pServiceTriggerInfo   = IntPtr.Zero;

            try
            {
                // Marshal Guid struct NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID
                // and NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID to native memory

                int cbGuid = Marshal.SizeOf(typeof(Guid));
                pGuidIpAddressArrival = Marshal.AllocHGlobal(cbGuid);
                Marshal.StructureToPtr(NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID,
                                       pGuidIpAddressArrival, false);
                pGuidIpAddressRemoval = Marshal.AllocHGlobal(cbGuid);
                Marshal.StructureToPtr(NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID,
                                       pGuidIpAddressRemoval, false);

                // Allocate and set the SERVICE_TRIGGER structure for
                // NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID to start the service

                SERVICE_TRIGGER serviceTrigger1 = new SERVICE_TRIGGER();
                serviceTrigger1.dwTriggerType =
                    ServiceTriggerType.SERVICE_TRIGGER_TYPE_IP_ADDRESS_AVAILABILITY;
                serviceTrigger1.dwAction =
                    ServiceTriggerAction.SERVICE_TRIGGER_ACTION_SERVICE_START;
                serviceTrigger1.pTriggerSubtype = pGuidIpAddressArrival;

                // Allocate and set the SERVICE_TRIGGER structure for
                // NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID to stop the service

                SERVICE_TRIGGER serviceTrigger2 = new SERVICE_TRIGGER();
                serviceTrigger2.dwTriggerType =
                    ServiceTriggerType.SERVICE_TRIGGER_TYPE_IP_ADDRESS_AVAILABILITY;
                serviceTrigger2.dwAction =
                    ServiceTriggerAction.SERVICE_TRIGGER_ACTION_SERVICE_STOP;
                serviceTrigger2.pTriggerSubtype = pGuidIpAddressRemoval;

                // Marshal the 2 SERVICE_TRIGGER structs to native memory as an array

                int cbServiceTrigger = Marshal.SizeOf(typeof(SERVICE_TRIGGER));
                pServiceTriggers = Marshal.AllocHGlobal(cbServiceTrigger * 2);
                Marshal.StructureToPtr(serviceTrigger1, pServiceTriggers, false);
                Marshal.StructureToPtr(serviceTrigger2,
                                       new IntPtr((long)pServiceTriggers + cbServiceTrigger), false);

                // Allocate and set the SERVICE_TRIGGER_INFO structure

                SERVICE_TRIGGER_INFO serviceTriggerInfo = new SERVICE_TRIGGER_INFO();
                serviceTriggerInfo.cTriggers = 2;
                serviceTriggerInfo.pTriggers = pServiceTriggers;

                // Marshal the SERVICE_TRIGGER_INFO struct to native memory

                int cbServiceTriggerInfo = Marshal.SizeOf(typeof(SERVICE_TRIGGER_INFO));
                pServiceTriggerInfo = Marshal.AllocHGlobal(cbServiceTriggerInfo);
                Marshal.StructureToPtr(serviceTriggerInfo, pServiceTriggerInfo, false);

                // Call ChangeServiceConfig2 with the SERVICE_CONFIG_TRIGGER_INFO level
                // and pass to it the address of the SERVICE_TRIGGER_INFO structure

                if (!NativeMethods.ChangeServiceConfig2(hService,
                                                        ServiceConfig2InfoLevel.SERVICE_CONFIG_TRIGGER_INFO,
                                                        pServiceTriggerInfo))
                {
                    // If the handle is invalid, get the last Win32 error and throw a
                    // Win32Exception
                    throw new Win32Exception();
                }
            }
            finally
            {
                // Clean up the native memory

                if (pGuidIpAddressArrival != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pGuidIpAddressArrival);
                }

                if (pGuidIpAddressRemoval != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pGuidIpAddressRemoval);
                }

                if (pServiceTriggers != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pServiceTriggers);
                }

                if (pServiceTriggerInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pServiceTriggerInfo);
                }
            }
        }
        /// <summary>
        /// Set the service to trigger-start when a generic USB disk becomes available.
        /// </summary>
        /// <param name="hService">
        /// A handle to the service. This handle is returned by the OpenService or
        /// CreateService function and must have the SERVICE_CHANGE_CONFIG access right.
        /// </param>
        public static void SetServiceTriggerStartOnUSBArrival(SafeServiceHandle hService)
        {
            IntPtr pGuidUSBDevice      = IntPtr.Zero;
            IntPtr pUSBHardwareId      = IntPtr.Zero;
            IntPtr pDeviceData         = IntPtr.Zero;
            IntPtr pServiceTrigger     = IntPtr.Zero;
            IntPtr pServiceTriggerInfo = IntPtr.Zero;

            try
            {
                // Marshal the Guid struct GUID_DEVINTERFACE_DISK to native memory

                pGuidUSBDevice = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
                Marshal.StructureToPtr(GUID_DEVINTERFACE_DISK, pGuidUSBDevice, false);

                // Allocate and set the SERVICE_TRIGGER_SPECIFIC_DATA_ITEM structure

                SERVICE_TRIGGER_SPECIFIC_DATA_ITEM deviceData;
                deviceData.dwDataType =
                    ServiceTriggerDataType.SERVICE_TRIGGER_DATA_TYPE_STRING;
                deviceData.cbData = (uint)(USBHardwareId.Length + 1) * 2;
                pUSBHardwareId    = Marshal.StringToHGlobalUni(USBHardwareId);
                deviceData.pData  = pUSBHardwareId;

                // Marshal SERVICE_TRIGGER_SPECIFIC_DATA_ITEM to native memory

                int cbDataItem = Marshal.SizeOf(typeof(SERVICE_TRIGGER_SPECIFIC_DATA_ITEM));
                pDeviceData = Marshal.AllocHGlobal(cbDataItem);
                Marshal.StructureToPtr(deviceData, pDeviceData, false);

                // Allocate and set the SERVICE_TRIGGER structure

                SERVICE_TRIGGER serviceTrigger = new SERVICE_TRIGGER();
                serviceTrigger.dwTriggerType =
                    ServiceTriggerType.SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL;
                serviceTrigger.dwAction =
                    ServiceTriggerAction.SERVICE_TRIGGER_ACTION_SERVICE_START;
                serviceTrigger.pTriggerSubtype = pGuidUSBDevice;
                serviceTrigger.cDataItems      = 1;
                serviceTrigger.pDataItems      = pDeviceData;

                // Marshal the SERVICE_TRIGGER struct to native memory

                int cbServiceTrigger = Marshal.SizeOf(typeof(SERVICE_TRIGGER));
                pServiceTrigger = Marshal.AllocHGlobal(cbServiceTrigger);
                Marshal.StructureToPtr(serviceTrigger, pServiceTrigger, false);

                // Allocate and set the SERVICE_TRIGGER_INFO structure

                SERVICE_TRIGGER_INFO serviceTriggerInfo = new SERVICE_TRIGGER_INFO();
                serviceTriggerInfo.cTriggers = 1;
                serviceTriggerInfo.pTriggers = pServiceTrigger;

                // Marshal the SERVICE_TRIGGER_INFO struct to native memory

                int cbServiceTriggerInfo = Marshal.SizeOf(typeof(SERVICE_TRIGGER_INFO));
                pServiceTriggerInfo = Marshal.AllocHGlobal(cbServiceTriggerInfo);
                Marshal.StructureToPtr(serviceTriggerInfo, pServiceTriggerInfo, false);

                // Call ChangeServiceConfig2 with the SERVICE_CONFIG_TRIGGER_INFO level
                // and pass to it the address of the SERVICE_TRIGGER_INFO structure

                if (!NativeMethods.ChangeServiceConfig2(hService,
                                                        ServiceConfig2InfoLevel.SERVICE_CONFIG_TRIGGER_INFO,
                                                        pServiceTriggerInfo))
                {
                    // If the handle is invalid, get the last Win32 error and throw a
                    // Win32Exception
                    throw new Win32Exception();
                }
            }
            finally
            {
                // Clean up the native memory

                if (pGuidUSBDevice != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pGuidUSBDevice);
                }

                if (pUSBHardwareId != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUSBHardwareId);
                }

                if (pDeviceData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pDeviceData);
                }

                if (pServiceTrigger != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pServiceTrigger);
                }

                if (pServiceTriggerInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pServiceTriggerInfo);
                }
            }
        }
Пример #5
0
        private void SetServiceTriggerStartOnCustomEvent(string serviceName)
        {
            using (ServiceController sc = new ServiceController(serviceName))
            {
                // Marshal Guid struct GUID_DEVINTERFACE_DISK to native memory
                IntPtr pGuidCustomEvent = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
                Marshal.StructureToPtr(CUSTOM_EVENT_GUID, pGuidCustomEvent, false);

                //// Allocate and set the SERVICE_TRIGGER_SPECIFIC_DATA_ITEM structure
                //SERVICE_TRIGGER_SPECIFIC_DATA_ITEM deviceData;
                //deviceData.dwDataType = ServiceTriggerDataType.SERVICE_TRIGGER_DATA_TYPE_STRING;
                //deviceData.cbData = (uint)(USBHardwareId.Length + 1) * 2;
                //IntPtr pUSBHardwareId = Marshal.StringToHGlobalUni(USBHardwareId);
                //deviceData.pData = pUSBHardwareId;
                //// Marshal the SERVICE_TRIGGER_SPECIFIC_DATA_ITEM struct to native memory
                //IntPtr pDeviceData = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(
                //    SERVICE_TRIGGER_SPECIFIC_DATA_ITEM)));
                //Marshal.StructureToPtr(deviceData, pDeviceData, false);

                // Allocate and set the SERVICE_TRIGGER structure
                SERVICE_TRIGGER serviceTrigger;
                serviceTrigger.dwTriggerType =
                    ServiceTriggerType.SERVICE_TRIGGER_TYPE_CUSTOM;
                serviceTrigger.dwAction =
                    ServiceTriggerAction.SERVICE_TRIGGER_ACTION_SERVICE_START;
                serviceTrigger.pTriggerSubtype = pGuidCustomEvent;
                serviceTrigger.cDataItems      = 0;
                serviceTrigger.pDataItems      = IntPtr.Zero;
                // Marshal the SERVICE_TRIGGER struct to native memory
                IntPtr pServiceTrigger = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(
                                                                                 SERVICE_TRIGGER)));
                Marshal.StructureToPtr(serviceTrigger, pServiceTrigger, false);

                // Allocate and set the SERVICE_TRIGGER_INFO structure.
                SERVICE_TRIGGER_INFO serviceTriggerInfo = new SERVICE_TRIGGER_INFO();
                serviceTriggerInfo.cTriggers = 1;
                serviceTriggerInfo.pTriggers = pServiceTrigger;
                // Marshal the SERVICE_TRIGGER_INFO struct to native memory
                IntPtr pServiceTriggerInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(
                                                                                     SERVICE_TRIGGER_INFO)));
                Marshal.StructureToPtr(serviceTriggerInfo, pServiceTriggerInfo, false);

                // Call ChangeServiceConfig2 with the SERVICE_CONFIG_TRIGGER_INFO level
                // and pass to it the address of the SERVICE_TRIGGER_INFO structure.
                bool bSuccess = ServiceNative.ChangeServiceConfig2(
                    sc.ServiceHandle.DangerousGetHandle(),
                    ServiceConfig2InfoLevel.SERVICE_CONFIG_TRIGGER_INFO, pServiceTriggerInfo);
                int errorCode = Marshal.GetLastWin32Error();

                // Clean up the native resources
                //Marshal.FreeHGlobal(pGuidUSBDevice);
                //Marshal.FreeHGlobal(pUSBHardwareId);
                //Marshal.FreeHGlobal(pDeviceData);
                Marshal.FreeHGlobal(pServiceTrigger);
                Marshal.FreeHGlobal(pServiceTriggerInfo);

                // If the service failed to be set as trigger start, throw the error
                // returned by the ChangeServiceConfig2 function.
                if (!bSuccess)
                {
                    Marshal.ThrowExceptionForHR(errorCode);
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Set the service to trigger-start when the first IP address on the TCP/IP
        /// networking stack becomes available, and trigger-stop when the last IP address on
        /// the TCP/IP networking stack becomes unavailable.
        /// </summary>
        /// <param name="serviceName"></param>
        private void SetServiceTriggerStartOnIPAddressArrival(string serviceName)
        {
            using (ServiceController sc = new ServiceController(serviceName))
            {
                // Marshal Guid struct NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID and
                // NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID to native memory
                IntPtr pGuidIpAddressArrival = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
                Marshal.StructureToPtr(NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID,
                                       pGuidIpAddressArrival, false);
                IntPtr pGuidIpAddressRemoval = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
                Marshal.StructureToPtr(NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID,
                                       pGuidIpAddressRemoval, false);

                // Allocate and set the SERVICE_TRIGGER structure for
                // NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID to start the service
                SERVICE_TRIGGER serviceTrigger1 = new SERVICE_TRIGGER();
                serviceTrigger1.dwTriggerType =
                    ServiceTriggerType.SERVICE_TRIGGER_TYPE_IP_ADDRESS_AVAILABILITY;
                serviceTrigger1.dwAction =
                    ServiceTriggerAction.SERVICE_TRIGGER_ACTION_SERVICE_START;
                serviceTrigger1.pTriggerSubtype = pGuidIpAddressArrival;

                // Allocate and set the SERVICE_TRIGGER structure for
                // NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID to stop the service
                SERVICE_TRIGGER serviceTrigger2 = new SERVICE_TRIGGER();
                serviceTrigger2.dwTriggerType =
                    ServiceTriggerType.SERVICE_TRIGGER_TYPE_IP_ADDRESS_AVAILABILITY;
                serviceTrigger2.dwAction =
                    ServiceTriggerAction.SERVICE_TRIGGER_ACTION_SERVICE_STOP;
                serviceTrigger2.pTriggerSubtype = pGuidIpAddressRemoval;

                // Marshal the two SERVICE_TRIGGER structs to native memory as an array
                IntPtr pServiceTriggers = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(
                                                                                  SERVICE_TRIGGER)) * 2 /*2 elements*/);
                Marshal.StructureToPtr(serviceTrigger1, pServiceTriggers, false);
                Marshal.StructureToPtr(serviceTrigger2, new IntPtr((long)pServiceTriggers +
                                                                   Marshal.SizeOf(typeof(SERVICE_TRIGGER))), false);

                // Allocate and set the SERVICE_TRIGGER_INFO structure
                SERVICE_TRIGGER_INFO serviceTriggerInfo = new SERVICE_TRIGGER_INFO();
                serviceTriggerInfo.cTriggers = 2;
                serviceTriggerInfo.pTriggers = pServiceTriggers;
                // Marshal the SERVICE_TRIGGER_INFO struct to native memory
                IntPtr pServiceTriggerInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(
                                                                                     SERVICE_TRIGGER_INFO)));
                Marshal.StructureToPtr(serviceTriggerInfo, pServiceTriggerInfo, false);

                // Call ChangeServiceConfig2 with the SERVICE_CONFIG_TRIGGER_INFO level
                // and pass to it the address of the SERVICE_TRIGGER_INFO structure.
                bool bSuccess = ServiceNative.ChangeServiceConfig2(
                    sc.ServiceHandle.DangerousGetHandle(),
                    ServiceConfig2InfoLevel.SERVICE_CONFIG_TRIGGER_INFO, pServiceTriggerInfo);
                int errorCode = Marshal.GetLastWin32Error();

                // Clean up the native resources
                Marshal.FreeHGlobal(pGuidIpAddressArrival);
                Marshal.FreeHGlobal(pGuidIpAddressRemoval);
                Marshal.FreeHGlobal(pServiceTriggers);
                Marshal.FreeHGlobal(pServiceTriggerInfo);

                // If the service failed to be set as trigger start, throw the error
                // returned by the ChangeServiceConfig2 function.
                if (!bSuccess)
                {
                    Marshal.ThrowExceptionForHR(errorCode);
                }
            }
        }