Пример #1
0
        /// <summary>
        /// Sets the failure actions for the specified service
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="sfa"></param>
        internal static void SetFailureActions(string serviceName, ref NativeMethods.SERVICE_FAILURE_ACTIONS sfa)
        {
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            IntPtr lockHandle = NativeMethods.NullIntPtr;
            IntPtr scmHandle  = NativeMethods.NullIntPtr;
            IntPtr svcHandle  = NativeMethods.NullIntPtr;

            try
            {
                scmHandle = ServiceConfigurationHandler.GetSCMHandle();

                //lock the database
                lockHandle = RepeatLockServiceDatabase(scmHandle);
                if (NativeMethods.NullIntPtr.Equals(lockHandle))
                {
                    SetupLogger.LogError("BackEnd.Configure: Got back NULL service handle!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Setup was unable to configure service {0}", serviceName));
                }

                svcHandle = NativeMethods.OpenService(
                    scmHandle,
                    serviceName,
                    NativeMethods.SERVICE_CHANGE_CONFIG | NativeMethods.SERVICE_START);//since we set restart as a failure option, the handle should have SERVICE_START rights
                if (NativeMethods.NullIntPtr.Equals(svcHandle))
                {
                    //throw exception here
                    SetupLogger.LogInfo("BackEnd.Configure: Got back NULL service handle!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Setup was unable to configure service {0}", serviceName));
                }

                SetupLogger.LogInfo("BackEnd.Configure: Successfully opened {0} service", serviceName);

                bool success = NativeMethods.ChangeServiceConfig2(svcHandle, NativeMethods.SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa);
                if (!success)
                {
                    SetupLogger.LogInfo("BackEnd.Configure: Couldn't modify service description!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Setup was unable to configure service {0}", serviceName));
                }
            }
            finally
            {
                if (!NativeMethods.NullIntPtr.Equals(lockHandle))
                {
                    NativeMethods.UnlockServiceDatabase(lockHandle);
                }
                if (!NativeMethods.NullIntPtr.Equals(svcHandle))
                {
                    NativeMethods.CloseServiceHandle(svcHandle);
                }
                if (!NativeMethods.NullIntPtr.Equals(scmHandle))
                {
                    NativeMethods.CloseServiceHandle(scmHandle);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Create the engine service and start it
        /// </summary>
        public static void ConfigureCMPWorkerService(ServiceConfigurationHandler serviceConfigurationHandler)
        {
            AppAssert.AssertNotNull(serviceConfigurationHandler, "serviceConfigurationHandler");

            string installPath = SetupConstants.GetServerInstallPath();

            //attempt to remove services first.
            //this will ignore errors of service does not exist and service marked for deletion
            //If service is marked for deletion, then exception will be thrown at create time as
            //we will be unable to create the service.
            //reason:
            //1. Keeps the code path of Install and Repair same
            //2. Handles corner case of service already existing in Install mode
            //3. Repairs the configuration of the service if broken

            IntPtr hSCManager = NativeMethods.NullIntPtr;
            IntPtr password   = NativeMethods.NullIntPtr;

            try
            {
                hSCManager = ServiceConfigurationHandler.GetSCMHandle();

                //TODO: Handle rollback if exception is thrown
                ServiceConfigurationHandler.StopAndRemoveService(hSCManager, SetupConstants.EngineServiceName);

                //construct paths to service binaries
                string servicePathEngine = PathHelper.QuoteString(installPath + @"MSIT\CmpWorkerService\" + SetupConstants.EngineServiceBinary);
                SetupLogger.LogInfo("BackEnd.Configure: Engine Service path is : {0}", servicePathEngine);

                //Get account
                string userAccountName   = null;
                bool   runasLocalAccount = SetupInputs.Instance.FindItem(SetupInputTags.CmpServiceLocalAccountTag);
                if (!runasLocalAccount)
                {
                    userAccountName = UserAccountHelper.GetVmmServiceDomainAccount();
                    password        = Marshal.SecureStringToGlobalAllocUnicode(SetupInputs.Instance.FindItem(SetupInputTags.CmpServiceUserPasswordTag));
                }

                //create engine service
                ServiceConfigurationHandler.CreateService(
                    hSCManager,
                    SetupConstants.EngineServiceName,
                    Resources.EngineServiceDisplayName,
                    Resources.EngineServiceDescription,
                    servicePathEngine,
                    null,   // dependent services
                    userAccountName,
                    password: password,
                    autoStart: true,
                    interactive: false);

                //set failure actions for VMMService
                NativeMethods.SERVICE_FAILURE_ACTIONS sfa = new NativeMethods.SERVICE_FAILURE_ACTIONS();
                NativeMethods.SC_ACTION[]             sca = new NativeMethods.SC_ACTION[SetupConstants.ServiceActionsCount + 1];
                for (int i = 0; i < SetupConstants.ServiceActionsCount; i++)
                {
                    sca[i].Delay = SetupConstants.ServiceRestartDelay;
                    sca[i].Type  = NativeMethods.SC_ACTION_TYPE.SC_ACTION_RESTART;
                }
                sca[SetupConstants.ServiceActionsCount].Delay = 0;
                sca[SetupConstants.ServiceActionsCount].Type  = NativeMethods.SC_ACTION_TYPE.SC_ACTION_NONE;

                IntPtr unmanagedStructArray = NativeMethods.NullIntPtr;
                try
                {
                    unmanagedStructArray = GetUnmanagedStructArray(sca);

                    sfa.sc_Action     = unmanagedStructArray;
                    sfa.cActions      = SetupConstants.ServiceActionsCount + 1;
                    sfa.dwResetPeriod = SetupConstants.ServiceResetPeriod;
                    sfa.lpCommand     = null;
                    sfa.lpRebootMsg   = null;

                    //set service failure actions for engine service
                    ServiceConfigurationHandler.SetFailureActions(SetupConstants.EngineServiceName, ref sfa);

                    //ConfigurationProgressEvent(this, new EventArgs());
                }
                finally
                {
                    if (NativeMethods.NullIntPtr != unmanagedStructArray)
                    {
                        Marshal.FreeHGlobal(unmanagedStructArray);
                    }
                }
            }
            finally
            {
                if (!NativeMethods.NullIntPtr.Equals(hSCManager))
                {
                    NativeMethods.CloseServiceHandle(hSCManager);
                }
                if (!NativeMethods.NullIntPtr.Equals(password))
                {
                    Marshal.ZeroFreeGlobalAllocUnicode(password);
                }
            }
        }