Ejemplo n.º 1
0
        /// <summary>
        /// Attempts to stop a service
        /// Waits for timeout period for the service to stop
        /// Logs result and returns.
        /// </summary>
        /// <param name="serviceName"></param>
        private static void StopService(string serviceName)
        {
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            SetupLogger.LogInfo("ServiceConfigurationHandler.StopService: Stop the service {0}", serviceName);

            try
            {
                //InspectHelper.StopService(serviceName);
                using (ServiceController serviceController = new ServiceController(serviceName))
                {
                    // Check if the service is stopped or paused
                    if (serviceController.Status == ServiceControllerStatus.Stopped)
                    {
                        // Service is stopped, log and return
                        return;
                    }
                    serviceController.Stop();
                    serviceController.WaitForStatus(ServiceControllerStatus.Stopped, ServiceStopTimeout);
                }
            }
            catch (Exception e)
            {
                SetupLogger.LogException(e);
                throw new Exception(String.Format("Cannot stop the {0} service", serviceName));
            }
        }
Ejemplo n.º 2
0
        private static bool RemoveService(IntPtr hSCManager, string serviceName)
        {
            ServiceDeleteStatus status = ServiceConfigurationHandler.StopAndRemoveService(hSCManager, serviceName);
            bool isRemoved             = true;

            switch (status)
            {
            case ServiceDeleteStatus.ServiceDeleteFailed:
            {
                isRemoved = false;
                break;
            }

            case ServiceDeleteStatus.ServiceDeleteSuccess:
            {
                isRemoved = true;
                break;
            }

            default:
            {
                AppAssert.Assert(false, "Unexpected ServiceDeleteStatus returned");
                isRemoved = false;
                break;
            }
            }

            return(isRemoved);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// This method stops a given service and deletes it. The SCM handle passed must have standard rights.
        /// It handles the case of service not being in started mode.
        /// </summary>
        /// <param name="hSCManager">Handle to SCM with standard rights</param>
        /// <param name="svcName">Name of the service to be deleted</param>
        public static ServiceDeleteStatus StopAndRemoveService(IntPtr hSCManager, string svcName)
        {
            AppAssert.Assert(NativeMethods.NullIntPtr != hSCManager, "Invalid SC Manager handle!");
            AppAssert.Assert(null != svcName, "Null service name passed!");

            //return success if the service doesn't exist
            if (ServiceConfigurationHandler.CheckServiceExists(hSCManager, svcName) == false)
            {
                return(ServiceDeleteStatus.ServiceDeleteSuccess);
            }

            // stop and delete the service
            try
            {
                //stop the service
                ServiceConfigurationHandler.StopService(svcName);

                ServiceConfigurationHandler.DeleteService(hSCManager, svcName);//throws ServiceConfigurationException if delete failed
            }
            catch
            {
                return(ServiceDeleteStatus.ServiceDeleteFailed);
            }

            //state: Delete succeeded
            return(ServiceDeleteStatus.ServiceDeleteSuccess);
        }
Ejemplo n.º 4
0
        private static int MapServiceStartModeToNative(ServiceStartMode startMode)
        {
            switch (startMode)
            {
            case ServiceStartMode.Automatic:
            {
                return(NativeMethods.SERVICE_AUTO_START);
            }

            case ServiceStartMode.Manual:
            {
                return(NativeMethods.SERVICE_DEMAND_START);
            }

            case ServiceStartMode.Disabled:
            {
                return(NativeMethods.SERVICE_DISABLED);
            }

            default:
            {
                AppAssert.Assert(false, "Code should not reach here");
                return(NativeMethods.SERVICE_DEMAND_START);
            }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Deletes a registry value under specified key
        /// </summary>
        /// <param name="root"></param>
        /// <param name="registryKeyPath"></param>
        /// <param name="name"></param>
        /// <exception cref="BackEndErrorException"></exception>
        public static void DeleteRegistryValue(RegistryKey root, String registryKeyPath, String name)
        {
            AppAssert.AssertNotNull(root, "root");
            AppAssert.AssertNotNull(registryKeyPath, "registryKeyPath");
            AppAssert.AssertNotNull(name, "name");

            try
            {
                using (RegistryKey regkey = root.OpenSubKey(registryKeyPath, true))
                {
                    if (regkey != null)
                    {
                        regkey.DeleteValue(name, false);
                    }
                }
            }
            catch (System.Security.SecurityException se)
            {
                throw new Exception("Cannot access registry key" + registryKeyPath);
            }
            catch (UnauthorizedAccessException uae)
            {
                throw new Exception("Cannot access registry key" + registryKeyPath);
            }
        }
Ejemplo n.º 6
0
        public static string GetFullyQualifiedName(string computerName)
        {
            string result = null;

            AppAssert.AssertNotNull(computerName);

            try
            {
                IPAddress ipAddress = null;
                if (IPAddress.TryParse(computerName, out ipAddress))
                {
                    result = Dns.GetHostEntry(ipAddress).HostName;
                }
                else
                {
                    result = Dns.GetHostEntry(computerName).HostName;
                }
            }
            catch (ArgumentException e)
            {
                throw new Exception("Compute name is invalid");
            }
            catch (System.Net.Sockets.SocketException e)
            {
                throw new Exception("Cannot contact the machine with name " + computerName);
            }

            return(result);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Checks if a service exists.
        /// </summary>
        /// <param name="hSCManager">Handle to SCM</param>
        /// <param name="serviceName">Name of the service</param>
        /// <returns></returns>
        public static bool CheckServiceExists(IntPtr hSCManager, string serviceName)
        {
            AppAssert.Assert(NativeMethods.NullIntPtr != hSCManager, "Invalid SC Manager handle!");
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            IntPtr hSvc = NativeMethods.NullIntPtr;

            try
            {
                hSvc = NativeMethods.OpenService(hSCManager, serviceName, NativeMethods.SERVICE_QUERY_CONFIG);
                if (NativeMethods.NullIntPtr.Equals(hSvc))
                {
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    if (NativeMethods.ERROR_SERVICE_DOES_NOT_EXIST == lastWin32Error)
                    {
                        return(false);
                    }
                    else
                    {
                        throw new Exception(String.Format("Cannot connect to the service {0}", serviceName));
                    }
                }
                else
                {
                    return(true);
                }
            }
            finally
            {
                if (!NativeMethods.NullIntPtr.Equals(hSvc))
                {
                    NativeMethods.CloseServiceHandle(hSvc);
                }
            }
        }
Ejemplo n.º 8
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);
                }
            }
        }
Ejemplo n.º 9
0
 public static byte[] GetBinarySid(SecurityIdentifier sid)
 {
     // Converts sid to binary form
     AppAssert.Assert(sid != null);
     if (sid == null)
     {
         throw new ArgumentNullException("sid");
     }
     byte[] sidbuff = new byte[sid.BinaryLength];
     sid.GetBinaryForm(sidbuff, 0);
     return(sidbuff);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Check installed products with Upgrade code
        /// </summary>
        /// <param name="upgradeCode"></param>
        /// <param name="foundAtleastOneVersion"></param>
        /// <param name="maxInstalledVersion"></param>
        /// <returns></returns>
        public static List <string> CheckProductByUpgradeCode(String upgradeCode, ref Version maxInstalledVersion)
        {
            //initializations
            List <string> result       = new List <string>();
            string        productCode  = String.Empty;
            UInt32        error        = 0;//for holding return values from native APIs
            StringBuilder queryVersion = new StringBuilder(SetupConstants.MaximumVersionStringLength);
            UInt32        bufferLength = (UInt32)queryVersion.Capacity;

            int           index = 0;
            UInt32        enumRelatedProdResult = 0;
            StringBuilder productCodeBuffer     = new StringBuilder(SetupConstants.MaximumUpgradeCodeLength);

            enumRelatedProdResult = CMP.Setup.Helpers.NativeMethods.MsiEnumRelatedProducts(upgradeCode, 0, index, productCodeBuffer);

            while (CMP.Setup.Helpers.NativeMethods.ERROR_SUCCESS == enumRelatedProdResult)
            {
                bufferLength = SetupConstants.MaximumVersionStringLength;
                error        = CMP.Setup.Helpers.NativeMethods.MsiGetProductInfo(productCodeBuffer.ToString(),
                                                                                 CMP.Setup.Helpers.NativeMethods.INSTALLPROPERTY_VERSIONSTRING,
                                                                                 queryVersion,
                                                                                 ref bufferLength);
                if (0 == error)
                {
                    // success
                    SetupLogger.LogInfo("CheckProductByUpgradeCode : found product with upgrade code {0} with version {1}", upgradeCode, queryVersion.ToString());
                    Version obtainedVersion = new Version(queryVersion.ToString());
                    SetupLogger.LogInfo("CheckProductByUpgradeCode: Installed Version {0}", queryVersion.ToString());
                    int res = obtainedVersion.CompareTo(maxInstalledVersion);
                    AppAssert.Assert(res != 0, "Cannot get two related products with same version! Something must be bad with your code");
                    if (res > 0)
                    {
                        maxInstalledVersion = obtainedVersion;
                    }

                    productCode = productCodeBuffer.ToString();
                    if (!result.Contains(productCode))
                    {
                        result.Add(productCode);
                    }
                }
                else
                {
                    //failed
                    SetupLogger.LogError("CheckProductByUpgradeCode : MsiGetProductInfo failed. Msi Error is {0}", error);
                }
                index++;
                enumRelatedProdResult = CMP.Setup.Helpers.NativeMethods.MsiEnumRelatedProducts(upgradeCode, 0, index, productCodeBuffer);
            }//end of while

            return(result);
        }
Ejemplo n.º 11
0
        public static SecurityIdentifier GetSecurityIdentifier(string accountName)
        {
            AppAssert.Assert(!string.IsNullOrEmpty(accountName));

            // Check if the string is null or empty - these are not valid account names
            if (string.IsNullOrEmpty(accountName))
            {
                throw new IdentityNotMappedException();
            }

            // verify that the entered string is a valid account name
            return(UserAccountHelper.GetSecurityIdentifier(new NTAccount(accountName.Trim())));
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Restarts a particular service
        /// The method times out if service does not reach "Running" status within the timeout period.
        /// </summary>
        /// <param name="serviceName">name of service to start</param>
        /// <exception cref="ServiceConfigurationException">when  service could not be started</exception>
        public void RestartService(String serviceName)
        {
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            SetupLogger.LogInfo("ServiceConfigurationHandler.RestartService: Start the service {0}", serviceName);

            try
            {
                this.StartService(serviceName);
            }
            catch (Exception serviceNotFoundException)
            {
                SetupLogger.LogInfo("ServiceConfigurationHandler.StartService: Start the service, exception {0}", serviceNotFoundException);
                throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Attempts to delete the service
        /// Does nothing if the service doesn't exist
        /// Throws exception only if the delete actually failed
        /// </summary>
        /// <param name="hSCManager"></param>
        /// <param name="svcName"></param>
        private static void DeleteService(IntPtr hSCManager, string svcName)
        {
            AppAssert.Assert(NativeMethods.NullIntPtr != hSCManager, "Invalid SC Manager handle!");
            AppAssert.Assert(null != svcName, "Null service name passed!");

            IntPtr hSvc = NativeMethods.NullIntPtr;

            try
            {
                hSvc = NativeMethods.OpenService(hSCManager, svcName, NativeMethods.DELETE);
                if (NativeMethods.NullIntPtr.Equals(hSvc))
                {
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    if (
                        ((NativeMethods.ERROR_SERVICE_DOES_NOT_EXIST != lastWin32Error) &&
                         (NativeMethods.ERROR_SERVICE_MARKED_FOR_DELETE != lastWin32Error))
                        )
                    {
                        throw new Exception(String.Format("Cannot connect to the service.\nService name: {0}", svcName));
                    }
                    else
                    {
                        //no exception if the service doesn't exist.
                        return;
                    }
                }

                //got a handle to the service... let's try to delete it.
                bool deleteSvcReturn = NativeMethods.DeleteService(hSvc);
                if (!deleteSvcReturn)
                {
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    SetupLogger.LogInfo("Couldn't delete service: Doing get last error: {0}.", lastWin32Error);
                    throw new Exception(String.Format("Setup could not delete service {0}", svcName));
                }
            }
            finally
            {
                if (!NativeMethods.NullIntPtr.Equals(hSvc))
                {
                    NativeMethods.CloseServiceHandle(hSvc);
                }
                SetupLogger.LogInfo("ServiceConfigurationHandler.DeleteService: Doing get last error after closing service handle: {0}", Marshal.GetLastWin32Error());
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Sets status of the specified service to the specified value
        /// Ideally this method should throw an exception with the Win32 error value.
        /// As of now it returns the error code to the caller
        /// </summary>
        /// <param name="hSCManager"></param>
        /// <param name="svcName"></param>
        /// <param name="serviceStatus"></param>
        /// <returns></returns>
        private static int SetServiceStatus(IntPtr hSCManager, string svcName, int serviceStatus)
        {
            AppAssert.Assert(NativeMethods.NullIntPtr != hSCManager, "Invalid SC Manager handle!");
            AppAssert.Assert(null != svcName, "Null service name passed!");

            int    returnCode = 0;
            IntPtr svcHandle  = NativeMethods.NullIntPtr;

            try
            {
                svcHandle = NativeMethods.OpenService(hSCManager, svcName, NativeMethods.SERVICE_CHANGE_CONFIG);
                if (NativeMethods.NullIntPtr.Equals(svcHandle))
                {
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Cannot connect to the service.\nService name: {0}", svcName));
                }

                NativeMethods.ChangeServiceConfig(
                    svcHandle,
                    NativeMethods.SERVICE_NO_CHANGE,
                    serviceStatus,
                    NativeMethods.SERVICE_NO_CHANGE,
                    null,
                    null,
                    NativeMethods.NullIntPtr,
                    null,
                    null,
                    null,
                    null
                    );

                returnCode = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                return(returnCode);
            }
            finally
            {
                if (!NativeMethods.NullIntPtr.Equals(svcHandle))
                {
                    NativeMethods.CloseServiceHandle(svcHandle);
                }
            }
        }
Ejemplo n.º 15
0
 static public void AssertNotNull(object parameter)
 {
     AppAssert.InternalAssert(3, parameter != null, "Null argument");
 }
Ejemplo n.º 16
0
 static public void AssertNotNull(object parameter, string parameterName)
 {
     AppAssert.InternalAssert(3, parameter != null,
                              "The parameter '{0}' is null.", parameterName);
 }
Ejemplo n.º 17
0
 static public void Fail(string message = null, params object[] formatArgs)
 {
     message = message ?? "Assertion failed";
     AppAssert.InternalAssert(3, false, message, formatArgs);
 }
Ejemplo n.º 18
0
 static public void Assert(bool condition)
 {
     AppAssert.InternalAssert(3, condition, "Assertion failed");
 }
Ejemplo n.º 19
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);
                }
            }
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Get the account name given a Sid
 /// </summary>
 /// <param name="id"></param>
 /// <returns></returns>
 public static string GetAccountNameFromSid(SecurityIdentifier id)
 {
     AppAssert.AssertNotNull(id);
     return(id.Translate(typeof(NTAccount)).Value);
 }
Ejemplo n.º 21
0
 static public void Assert(bool condition, string format, params object[] formatArgs)
 {
     AppAssert.InternalAssert(3, condition, format, formatArgs);
 }
Ejemplo n.º 22
0
        /// <summary>
        /// This method calls into native code for creating a service.
        /// The service is created with the following standard parameters:
        /// WIN32_OWN_PROCESS, ERROR_NORMAL, No dependencies
        /// The handle of the service obtained is closed and not returned
        /// </summary>
        /// <param name="hSCManager">Handle to SCM with create service rights</param>
        /// <param name="svcName">Name of service to create</param>
        /// <param name="displayName">Localized display name of the service</param>
        /// <param name="svcDescription">Description of the service</param>
        /// <param name="binaryPath">Path to the binary</param>
        /// <param name="dependenciesArray">Array of dependencies</param>
        /// <param name="serviceStartName">The user account under which the service will run</param>
        /// <param name="password">Password for the user account</param>
        /// <param name="autoStart">Should the service be AutoStart on booting the machine</param>
        /// <param name="interactive">Allow service to interact with desktop or not</param>
        public static void CreateService(IntPtr hSCManager,
                                         string svcName,
                                         string displayName,
                                         string svcDescription,
                                         string binaryPath,
                                         string[] dependenciesArray,
                                         string serviceStartName,
                                         IntPtr password,
                                         bool autoStart,
                                         bool interactive)
        {
            IntPtr hService = NativeMethods.NullIntPtr;

            try
            {
                AppAssert.Assert(null != svcName, "Null service name passed!");
                AppAssert.Assert(null != binaryPath, "Null binary path passed!");

                string dependenciesString = CreateNativeStringArray(dependenciesArray);

                int svcType = NativeMethods.SERVICE_WIN32_OWN_PROCESS;
                if (interactive)
                {
                    svcType = NativeMethods.SERVICE_WIN32_OWN_PROCESS | NativeMethods.SERVICE_INTERACTIVE_PROCESS;
                }

                int svcStartType = NativeMethods.SERVICE_DEMAND_START;
                if (autoStart)
                {
                    svcStartType = NativeMethods.SERVICE_AUTO_START;
                }

                if (!NativeMethods.NullIntPtr.Equals(password))
                //if we are using a password we need to gr  ant logon as service permissions to this user.
                {
                    try
                    {
                        NativeMethods.SetRight(serviceStartName, "SeServiceLogonRight", true);
                        NativeMethods.SetRight(serviceStartName, "SeAssignPrimaryTokenPrivilege", true);
                    }
                    catch (Exception exp)
                    {
                        SetupLogger.LogError("Failed to grant user ( " + serviceStartName +
                                             " ) logon as service permissions. Error: " + exp.Message);
                    }
                }

                hService = NativeMethods.CreateService(
                    hSCManager,
                    svcName,
                    displayName,
                    NativeMethods.SERVICE_CHANGE_CONFIG,
                    svcType,
                    svcStartType,
                    NativeMethods.SERVICE_ERROR_NORMAL,
                    binaryPath,
                    null,                     //load order group
                    NativeMethods.NullIntPtr, //[out] tagId
                    dependenciesString,
                    serviceStartName,         //Username
                    password
                    );

                if (NativeMethods.NullIntPtr.Equals(hService))
                {
                    SetupLogger.LogInfo("BackEnd.Configure: Got back NULL service handle!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Cannot create service {0}", svcName));
                }

                NativeMethods.SERVICE_DESCRIPTION svcDesc = new NativeMethods.SERVICE_DESCRIPTION();
                svcDesc.lpDescription = svcDescription;
                bool success = NativeMethods.ChangeServiceConfig2(hService, NativeMethods.SERVICE_CONFIG_DESCRIPTION,
                                                                  ref svcDesc);

                if (!success)
                {
                    SetupLogger.LogInfo("BackEnd.Configure: Couldn't modify service description!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Cannot create service {0}", svcName));
                }

                // Set service SID type. This is required for any service that has a firewall rule targeted for that specific service.
                NativeMethods.SERVICE_SID_INFO svcSidType = new NativeMethods.SERVICE_SID_INFO();
                svcSidType.serviceSidType = NativeMethods.SERVICE_SID_TYPE.SERVICE_SID_TYPE_UNRESTRICTED;
                success = NativeMethods.ChangeServiceConfig2(hService, NativeMethods.SERVICE_CONFIG_SERVICE_SID_INFO,
                                                             ref svcSidType);

                if (!success)
                {
                    SetupLogger.LogInfo("BackEnd.Configure: Couldn't modify service SID type!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Cannot create service {0}", svcName));
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                if (NativeMethods.NullIntPtr != hService)
                {
                    NativeMethods.CloseServiceHandle(hService);
                }
            }
        }
Ejemplo n.º 23
0
 static public void Assert(bool condition, string message)
 {
     AppAssert.InternalAssert(3, condition, message);
 }
Ejemplo n.º 24
0
        /// <summary>
        /// Starts a particular service
        /// The method times out if service does not reach "Running" status within the timeout period.
        /// </summary>
        /// <param name="serviceName">name of service to start</param>
        /// <param name="machineName">name of computer on which the service resides</param>
        /// <exception cref="ServiceConfigurationException">when  service could not be started</exception>
        public void StartService(String serviceName, String machineName)
        {
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            SetupLogger.LogInfo("StartService: Start the service {0}", serviceName);
            //ConfigurationMessageEvent(this, new ConfigurationMessageEventArgs(String.Format(Resources.StartingService, serviceName)));
            try
            {
                AppAssert.AssertNotNull(serviceName, "serviceName");

                ServiceController serviceController = null;

                try
                {
                    SetupLogger.LogInfo("Starting service" + serviceName);

                    if (machineName == null)
                    {
                        serviceController = new ServiceController(serviceName); // local host
                    }
                    else
                    {
                        serviceController = new ServiceController(serviceName, machineName);
                    }

                    SetupLogger.LogInfo("StartService: Service {0} status = {1}", serviceName, serviceController.Status);

                    //
                    // Query configurations (credentials and start mode) of service
                    //
                    ServiceConfig serviceConfig = GetServiceConfig(serviceName, machineName);

                    //
                    // Check if the service is disabled or manual and stopped
                    //
                    if (serviceConfig.StartMode == ServiceStartMode.Disabled ||
                        (serviceConfig.StartMode == ServiceStartMode.Manual &&
                         serviceController.Status == ServiceControllerStatus.Stopped))
                    {
                        SetupLogger.LogInfo(
                            "StartService : service is disabled or manual and not running");

                        throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
                    }

                    // Check if the service is stopped or paused
                    if (serviceController.Status == ServiceControllerStatus.Running)
                    {
                        // Service is running, log and return

                        SetupLogger.LogInfo("StartService: Service running, check if needs to be restarted");

                        return;
                    }
                    if (serviceController.Status == ServiceControllerStatus.Stopped)
                    {
                        // Service stopped, Start the service

                        SetupLogger.LogInfo("StartService: Service stopped, Start the service");
                        serviceController.Start();
                    }
                    else if (serviceController.Status == ServiceControllerStatus.Paused)
                    {
                        // Service paused, Resume the service

                        SetupLogger.LogInfo("StartService: Service paused, Resume the service");
                        serviceController.Continue();
                    }

                    SetupLogger.LogInfo("StartService: Wait for service to start (timeout = {0})", SetupConstants.ServiceStartTimeout);
                    serviceController.WaitForStatus(ServiceControllerStatus.Running, SetupConstants.ServiceStartTimeout);
                }
                catch (System.ComponentModel.Win32Exception win32Exception)
                {
                    // The native service API failed
                    SetupLogger.LogError("StartService: Couldn't start service! Throwing exception: {0}", win32Exception.ToString());
                    throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
                }
                catch (InvalidOperationException invalidOperationException)
                {
                    // The service can not be started
                    SetupLogger.LogError("StartService: Couldn't start service! Throwing exception: {0}", invalidOperationException.ToString());
                    throw;
                }
                catch (System.ServiceProcess.TimeoutException timeoutException)
                {
                    // There was a timeout
                    SetupLogger.LogError("StartService: Couldn't start service! Throwing exception: {0}", timeoutException.ToString());
                    throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
                }
                finally
                {
                    if (serviceController != null)
                    {
                        serviceController.Close();
                    }
                }
            }
            catch (Exception serviceNotFoundException)
            {
                SetupLogger.LogInfo("ServiceConfigurationHandler.StartService: Start the service, exception {0}", serviceNotFoundException);
                throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
            }
        }