示例#1
0
        private void ProjectInstaller_AfterInstall(object sender,
               System.Configuration.Install.InstallEventArgs e)
        {
            //Our code goes in this event because it is the only one that will do
            //a proper job of letting the user know that an error has occurred,
            //if one indeed occurs. Installation will be rolled back
            //if an error occurs.

            int iSCManagerHandle = 0;
            int iSCManagerLockHandle = 0;
            int iServiceHandle = 0;
            bool bChangeServiceConfig = false;
            bool bChangeServiceConfig2 = false;
            modAPI.SERVICE_DESCRIPTION ServiceDescription;
            modAPI.SERVICE_FAILURE_ACTIONS ServiceFailureActions;
            modAPI.SC_ACTION[] ScActions = new modAPI.SC_ACTION[3];
            //There should be one element for each action.
            //The Services snap-in shows 3 possible actions.

            bool bCloseService = false;
            bool bUnlockSCManager = false;
            bool bCloseSCManager = false;

            IntPtr iScActionsPointer = new IntPtr();
            try
            {
                //Obtain a handle to the Service Control Manager,
                //with appropriate rights.
                //This handle is used to open the relevant service.
                iSCManagerHandle = modAPI.OpenSCManagerA(null, null,
                modAPI.ServiceControlManagerType.SC_MANAGER_ALL_ACCESS);

                //Check that it's open. If not throw an exception.
                if (iSCManagerHandle < 1)
                {
                    throw new Exception("Unable to open the Services Manager.");
                }

                //Lock the Service Control Manager database.
                iSCManagerLockHandle = modAPI.LockServiceDatabase(iSCManagerHandle);

                //Check that it's locked. If not throw an exception.
                if (iSCManagerLockHandle < 1)
                {
                    throw new Exception("Unable to lock the Services Manager.");
                }

                //Obtain a handle to the relevant service, with appropriate rights.
                //This handle is sent along to change the settings. The second parameter
                //should contain the name you assign to the service.
                iServiceHandle = modAPI.OpenServiceA(iSCManagerHandle, gServiceName,
                modAPI.ACCESS_TYPE.SERVICE_ALL_ACCESS);

                //Check that it's open. If not throw an exception.
                if (iServiceHandle < 1)
                {
                    throw new Exception("Unable to open the Service for modification.");
                }
                //Call ChangeServiceConfig to update the ServiceType
                //to SERVICE_INTERACTIVE_PROCESS.
                //Very important is that you do not leave out or change the other relevant
                //ServiceType settings. The call will return False if you do.
                //Also, only services that use the LocalSystem account can be set to
                //SERVICE_INTERACTIVE_PROCESS.
                modAPI.ServiceType servicetype = modAPI.ServiceType.SERVICE_WIN32_OWN_PROCESS;
                modAPI.ServiceStartType starttype = modAPI.ServiceStartType.SERVICESTARTTYPE_NO_CHANGE;

                if (sServiceType.IndexOf("auto",StringComparison.CurrentCultureIgnoreCase)>=0)
                    starttype =  modAPI.ServiceStartType.SERVICE_AUTO_START;

                if (sServiceUser== null || sServiceUser.Length < 1)
                {
                    servicetype = servicetype | modAPI.ServiceType.SERVICE_INTERACTIVE_PROCESS;
                    sServiceUser = null;
                    sServicePassword = null;
                }

                 bChangeServiceConfig = modAPI.ChangeServiceConfigA(iServiceHandle,
                     servicetype,
                     (int) starttype, modAPI.SERVICE_NO_CHANGE,
                      null, null, 0, null, sServiceUser, sServicePassword, null);
                //null, null, 0, null, null, null, null);

                //If the call is unsuccessful, throw an exception.
                if (bChangeServiceConfig == false)
                {
                    throw new Exception("Unable to change the Service settings.");
                }

            #if INTERACTIVESERVICE
                //To change the description, create an instance of the SERVICE_DESCRIPTION
                //structure and set the lpDescription member to your desired description.
                ServiceDescription.lpDescription =
                  "This is my custom description for my Windows Service Application!";

                //Call ChangeServiceConfig2 with SERVICE_CONFIG_DESCRIPTION in the second
                //parameter and the SERVICE_DESCRIPTION instance in the third parameter
                //to update the description.
                bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,
                modAPI.InfoLevel.SERVICE_CONFIG_DESCRIPTION, ref ServiceDescription);

                //If the update of the description is unsuccessful it is up to you to
                //throw an exception or not. The fact that the description did not update
                //should not impact the functionality of your service.
                if (bChangeServiceConfig2 == false)
                {
                    throw new Exception("Unable to set the Service description.");
                }
            #endif
                // The service control manager counts the number of times each service has failed since the system booted.
                // The count is reset to 0 if the service has not failed for dwResetPeriod seconds.
                // When the service fails for the Nth time, the service controller performs the action specified
                // in element [N-1] of the lpsaActions array.
                // If N is greater than cActions, the service controller repeats the last action in the array.

                //To change the Service Failure Actions, create an instance of the
                //SERVICE_FAILURE_ACTIONS structure and set the members to your
                //desired values. See MSDN for detailed descriptions.
                // modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART;
                // modAPI.SC_ACTION_TYPE.SC_ACTION_RUN_COMMAND;
                // modAPI.SC_ACTION_TYPE.SC_ACTION_REBOOT;

                ServiceFailureActions.dwResetPeriod = dwResetPeriod; // every 12 hours, will reboot every 24
                ServiceFailureActions.lpRebootMsg =
                         "Service failed to start! Rebooting...";
                ServiceFailureActions.lpCommand = "";
                ServiceFailureActions.cActions = ScActions.Length;

                //The lpsaActions member of SERVICE_FAILURE_ACTIONS is a pointer to an
                //array of SC_ACTION structures. This complicates matters a little,
                //and although it took me a week to figure it out, the solution
                //is quite simple. SC_ACTION_NONE

                //First order of business is to populate our array of SC_ACTION structures
                //with appropriate values.
                ScActions[0].Delay = 20000;
                ScActions[0].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART;
                ScActions[1].Delay = 20000;
                ScActions[1].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART;
                ScActions[2].Delay = 20000;
                ScActions[2].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART;

                //Once that's done, we need to obtain a pointer to a memory location
                //that we can assign to lpsaActions in SERVICE_FAILURE_ACTIONS.
                //We use 'Marshal.SizeOf(New modAPI.SC_ACTION) * 3' because we pass
                //3 actions to our service. If you have less
                //actions change the * 3 accordingly.
                iScActionsPointer =
                  Marshal.AllocHGlobal(Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);

                //Once we have obtained the pointer for the memory location we need to
                //fill the memory with our structure. We use the CopyMemory API function
                //for this. Please have a look at it's declaration in modAPI.
                modAPI.CopyMemory(iScActionsPointer,
                  ScActions, Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);

                //We set the lpsaActions member
                //of SERVICE_FAILURE_ACTIONS to the integer
                //value of our pointer.
                ServiceFailureActions.lpsaActions = iScActionsPointer.ToInt32();

                //We call bChangeServiceConfig2 with the relevant parameters.
                bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,
                      modAPI.InfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS,
                      ref ServiceFailureActions);

                //If the update of the failure actions
                //are unsuccessful it is up to you to
                //throw an exception or not. The fact that
                //the failure actions did not update
                //should not impact the functionality of your service.
                if (bChangeServiceConfig2 == false)
                {
                    throw new Exception("Unable to set the Service Failure Actions.");
                }
            }
            catch (Exception ex)
            {
                Logger.LogMessage(ex.Message, Logger.FATAL);
                //Throw the exception again so the installer can get to it
                throw new Exception(ex.Message);
            }
            finally
            {
                //Close the handles if they are open.
                Marshal.FreeHGlobal(iScActionsPointer);

                if (iServiceHandle > 0)
                {
                    bCloseService = modAPI.CloseServiceHandle(iServiceHandle);
                }

                if (iSCManagerLockHandle > 0)
                {
                    bUnlockSCManager = modAPI.UnlockServiceDatabase(iSCManagerLockHandle);
                }

                if (iSCManagerHandle != 0)
                {
                    bCloseSCManager = modAPI.CloseServiceHandle(iSCManagerHandle);
                }
            }
        }
示例#2
0
        private void ProjectInstaller_AfterInstall(object sender,
                                                   System.Configuration.Install.InstallEventArgs e)
        {
            //Our code goes in this event because it is the only one that will do
            //a proper job of letting the user know that an error has occurred,
            //if one indeed occurs. Installation will be rolled back
            //if an error occurs.

            int  iSCManagerHandle      = 0;
            int  iSCManagerLockHandle  = 0;
            int  iServiceHandle        = 0;
            bool bChangeServiceConfig  = false;
            bool bChangeServiceConfig2 = false;

            modAPI.SERVICE_DESCRIPTION     ServiceDescription;
            modAPI.SERVICE_FAILURE_ACTIONS ServiceFailureActions;
            modAPI.SC_ACTION[]             ScActions = new modAPI.SC_ACTION[3];
            //There should be one element for each action.
            //The Services snap-in shows 3 possible actions.

            bool bCloseService    = false;
            bool bUnlockSCManager = false;
            bool bCloseSCManager  = false;

            IntPtr iScActionsPointer = new IntPtr();

            try
            {
                //Obtain a handle to the Service Control Manager,
                //with appropriate rights.
                //This handle is used to open the relevant service.
                iSCManagerHandle = modAPI.OpenSCManagerA(null, null,
                                                         modAPI.ServiceControlManagerType.SC_MANAGER_ALL_ACCESS);

                //Check that it's open. If not throw an exception.
                if (iSCManagerHandle < 1)
                {
                    throw new Exception("Unable to open the Services Manager.");
                }

                //Lock the Service Control Manager database.
                iSCManagerLockHandle = modAPI.LockServiceDatabase(iSCManagerHandle);

                //Check that it's locked. If not throw an exception.
                if (iSCManagerLockHandle < 1)
                {
                    throw new Exception("Unable to lock the Services Manager.");
                }

                //Obtain a handle to the relevant service, with appropriate rights.
                //This handle is sent along to change the settings. The second parameter
                //should contain the name you assign to the service.
                iServiceHandle = modAPI.OpenServiceA(iSCManagerHandle, gServiceName,
                                                     modAPI.ACCESS_TYPE.SERVICE_ALL_ACCESS);

                //Check that it's open. If not throw an exception.
                if (iServiceHandle < 1)
                {
                    throw new Exception("Unable to open the Service for modification.");
                }
                //Call ChangeServiceConfig to update the ServiceType
                //to SERVICE_INTERACTIVE_PROCESS.
                //Very important is that you do not leave out or change the other relevant
                //ServiceType settings. The call will return False if you do.
                //Also, only services that use the LocalSystem account can be set to
                //SERVICE_INTERACTIVE_PROCESS.
                modAPI.ServiceType      servicetype = modAPI.ServiceType.SERVICE_WIN32_OWN_PROCESS;
                modAPI.ServiceStartType starttype   = modAPI.ServiceStartType.SERVICESTARTTYPE_NO_CHANGE;

                if (sServiceType.IndexOf("auto", StringComparison.CurrentCultureIgnoreCase) >= 0)
                {
                    starttype = modAPI.ServiceStartType.SERVICE_AUTO_START;
                }

                if (sServiceUser == null || sServiceUser.Length < 1)
                {
                    servicetype      = servicetype | modAPI.ServiceType.SERVICE_INTERACTIVE_PROCESS;
                    sServiceUser     = null;
                    sServicePassword = null;
                }

                bChangeServiceConfig = modAPI.ChangeServiceConfigA(iServiceHandle,
                                                                   servicetype,
                                                                   (int)starttype, modAPI.SERVICE_NO_CHANGE,
                                                                   null, null, 0, null, sServiceUser, sServicePassword, null);
                //null, null, 0, null, null, null, null);

                //If the call is unsuccessful, throw an exception.
                if (bChangeServiceConfig == false)
                {
                    throw new Exception("Unable to change the Service settings.");
                }

#if INTERACTIVESERVICE
                //To change the description, create an instance of the SERVICE_DESCRIPTION
                //structure and set the lpDescription member to your desired description.
                ServiceDescription.lpDescription =
                    "This is my custom description for my Windows Service Application!";

                //Call ChangeServiceConfig2 with SERVICE_CONFIG_DESCRIPTION in the second
                //parameter and the SERVICE_DESCRIPTION instance in the third parameter
                //to update the description.
                bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,
                                                                     modAPI.InfoLevel.SERVICE_CONFIG_DESCRIPTION, ref ServiceDescription);

                //If the update of the description is unsuccessful it is up to you to
                //throw an exception or not. The fact that the description did not update
                //should not impact the functionality of your service.
                if (bChangeServiceConfig2 == false)
                {
                    throw new Exception("Unable to set the Service description.");
                }
#endif
                // The service control manager counts the number of times each service has failed since the system booted.
                // The count is reset to 0 if the service has not failed for dwResetPeriod seconds.
                // When the service fails for the Nth time, the service controller performs the action specified
                // in element [N-1] of the lpsaActions array.
                // If N is greater than cActions, the service controller repeats the last action in the array.

                //To change the Service Failure Actions, create an instance of the
                //SERVICE_FAILURE_ACTIONS structure and set the members to your
                //desired values. See MSDN for detailed descriptions.
                // modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART;
                // modAPI.SC_ACTION_TYPE.SC_ACTION_RUN_COMMAND;
                // modAPI.SC_ACTION_TYPE.SC_ACTION_REBOOT;

                ServiceFailureActions.dwResetPeriod = dwResetPeriod; // every 12 hours, will reboot every 24
                ServiceFailureActions.lpRebootMsg   =
                    "Service failed to start! Rebooting...";
                ServiceFailureActions.lpCommand = "";
                ServiceFailureActions.cActions  = ScActions.Length;

                //The lpsaActions member of SERVICE_FAILURE_ACTIONS is a pointer to an
                //array of SC_ACTION structures. This complicates matters a little,
                //and although it took me a week to figure it out, the solution
                //is quite simple. SC_ACTION_NONE

                //First order of business is to populate our array of SC_ACTION structures
                //with appropriate values.
                ScActions[0].Delay        = 20000;
                ScActions[0].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART;
                ScActions[1].Delay        = 20000;
                ScActions[1].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART;
                ScActions[2].Delay        = 20000;
                ScActions[2].SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART;

                //Once that's done, we need to obtain a pointer to a memory location
                //that we can assign to lpsaActions in SERVICE_FAILURE_ACTIONS.
                //We use 'Marshal.SizeOf(New modAPI.SC_ACTION) * 3' because we pass
                //3 actions to our service. If you have less
                //actions change the * 3 accordingly.
                iScActionsPointer =
                    Marshal.AllocHGlobal(Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);

                //Once we have obtained the pointer for the memory location we need to
                //fill the memory with our structure. We use the CopyMemory API function
                //for this. Please have a look at it's declaration in modAPI.
                modAPI.CopyMemory(iScActionsPointer,
                                  ScActions, Marshal.SizeOf(new modAPI.SC_ACTION()) * 3);

                //We set the lpsaActions member
                //of SERVICE_FAILURE_ACTIONS to the integer
                //value of our pointer.
                ServiceFailureActions.lpsaActions = iScActionsPointer.ToInt32();

                //We call bChangeServiceConfig2 with the relevant parameters.
                bChangeServiceConfig2 = modAPI.ChangeServiceConfig2A(iServiceHandle,
                                                                     modAPI.InfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS,
                                                                     ref ServiceFailureActions);

                //If the update of the failure actions
                //are unsuccessful it is up to you to
                //throw an exception or not. The fact that
                //the failure actions did not update
                //should not impact the functionality of your service.
                if (bChangeServiceConfig2 == false)
                {
                    throw new Exception("Unable to set the Service Failure Actions.");
                }
            }
            catch (Exception ex)
            {
                Logger.LogMessage(ex.Message, Logger.FATAL);
                //Throw the exception again so the installer can get to it
                throw new Exception(ex.Message);
            }
            finally
            {
                //Close the handles if they are open.
                Marshal.FreeHGlobal(iScActionsPointer);

                if (iServiceHandle > 0)
                {
                    bCloseService = modAPI.CloseServiceHandle(iServiceHandle);
                }

                if (iSCManagerLockHandle > 0)
                {
                    bUnlockSCManager = modAPI.UnlockServiceDatabase(iSCManagerLockHandle);
                }

                if (iSCManagerHandle != 0)
                {
                    bCloseSCManager = modAPI.CloseServiceHandle(iSCManagerHandle);
                }
            }
        }