예제 #1
0
        private ServiceHandle GivenAServiceExists(string serviceName, bool canBeUpdated)
        {
            GivenTheServiceControlManagerCanBeOpened();

            var serviceHandle = A.Fake <ServiceHandle>(o => o.Wrapping(new ServiceHandle {
                NativeInterop = nativeInterop
            }));

            A.CallTo(() => serviceHandle.IsInvalid).Returns(value: false);

            ServiceHandle  dummyServiceHandle;
            Win32Exception dummyWin32Exception;

            A.CallTo(() => serviceControlManager.TryOpenService(serviceName, A <ServiceControlAccessRights> ._, out dummyServiceHandle, out dummyWin32Exception))
            .Returns(value: true)
            .AssignsOutAndRefParameters(serviceHandle, null);

            if (canBeUpdated)
            {
                A.CallTo(
                    () =>
                    nativeInterop.ChangeServiceConfigW(serviceHandle, A <ServiceType> ._, A <ServiceStartType> ._, A <ErrorSeverity> ._, A <string> ._,
                                                       A <string> ._, A <IntPtr> ._, A <string> ._, A <string> ._, A <string> ._, A <string> ._))
                .Returns(value: true);

                A.CallTo(() => nativeInterop.ChangeServiceConfig2W(serviceHandle, ServiceConfigInfoTypeLevel.ServiceDescription, A <IntPtr> ._))
                .Returns(value: true);
                A.CallTo(() => nativeInterop.ChangeServiceConfig2W(serviceHandle, ServiceConfigInfoTypeLevel.FailureActions, A <IntPtr> ._))
                .Returns(value: true);
                A.CallTo(() => nativeInterop.ChangeServiceConfig2W(serviceHandle, ServiceConfigInfoTypeLevel.FailureActionsFlag, A <IntPtr> ._))
                .Returns(value: true);
                A.CallTo(() => nativeInterop.ChangeServiceConfig2W(serviceHandle, ServiceConfigInfoTypeLevel.DelayedAutoStartInfo, A <IntPtr> ._))
                .ReturnsLazily((ServiceHandle handle, ServiceConfigInfoTypeLevel infoLevel, IntPtr info) =>
                {
                    if (info != IntPtr.Zero)
                    {
                        delayedAutoStartInfoSetOnNativeInterop = Marshal.ReadInt32(info) > 0;
                    }
                    else
                    {
                        delayedAutoStartInfoSetOnNativeInterop = null;
                    }
                    return(true);
                });

                A.CallTo(() => nativeInterop.StartServiceW(serviceHandle, A <uint> ._, A <IntPtr> ._))
                .Returns(value: true);
            }

            return(serviceHandle);
        }
예제 #2
0
        /// <summary>
        /// Installs the service.
        /// </summary>
        /// <param name="DisplayName">Service display name.</param>
        /// <param name="Description">Service description.</param>
        /// <param name="StartType">How the service should be started.</param>
        /// <param name="StartImmediately">If the service should be started immediately.</param>
        /// <param name="FailureActions">Service failure actions.</param>
        /// <param name="Credentials">Credentials to use when running service.</param>
        /// <returns>
        /// Return code:
        ///
        /// 0: Installed, not started.
        /// 1: Installed, started.
        /// 2: Updated, not started.
        /// 3: Updated, started.
        /// </returns>
        /// <exception cref="Exception">If service could not be installed.</exception>
        public int Install(string DisplayName, string Description, ServiceStartType StartType, bool StartImmediately,
                           ServiceFailureActions FailureActions, Win32ServiceCredentials Credentials)
        {
            string Path = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".exe");

            try
            {
                using (ServiceControlManager mgr = ServiceControlManager.Connect(null, null, ServiceControlManagerAccessRights.All))
                {
                    if (mgr.TryOpenService(this.serviceName, ServiceControlAccessRights.All, out ServiceHandle existingService,
                                           out Win32Exception errorException))
                    {
                        using (existingService)
                        {
                            existingService.ChangeConfig(DisplayName, Path, ServiceType.Win32OwnProcess,
                                                         StartType, ErrorSeverity.Normal, Credentials);

                            if (!string.IsNullOrEmpty(Description))
                            {
                                existingService.SetDescription(Description);
                            }

                            if (!(FailureActions is null))
                            {
                                existingService.SetFailureActions(FailureActions);
                                existingService.SetFailureActionFlag(true);
                            }
                            else
                            {
                                existingService.SetFailureActionFlag(false);
                            }

                            if (StartImmediately)
                            {
                                existingService.Start(throwIfAlreadyRunning: false);
                                return(3);
                            }
                            else
                            {
                                return(2);
                            }
                        }
        /// <summary>
        /// Creates the or update a windows service.
        /// Note that the service is not restarted due to changes in its configuration
        /// </summary>
        /// <param name="serviceDefinition">The service definition.</param>
        /// <param name="startImmediately">if set to <c>true</c> the service will be started immediatly after updating. Has no effect if the service is already running.</param>
        /// <exception cref="ArgumentException">
        /// Thrown when:
        /// BinaryPath of <paramref name="serviceDefinition"/> is null or empty
        /// or
        /// ServiceName of <paramref name="serviceDefinition"/> is null or empty
        /// </exception>
        /// <exception cref="PlatformNotSupportedException">Thrown when run on a non-windows platform.</exception>
        public void CreateOrUpdateService(ServiceDefinition serviceDefinition, bool startImmediately = false)
        {
            if (string.IsNullOrEmpty(serviceDefinition.BinaryPath))
            {
                throw new System.ArgumentException($"Invalid service definition. {nameof(ServiceDefinition.BinaryPath)} must not be null or empty.", nameof(serviceDefinition));
            }
            if (string.IsNullOrEmpty(serviceDefinition.ServiceName))
            {
                throw new System.ArgumentException($"Invalid service definition. {nameof(ServiceDefinition.ServiceName)} must not be null or empty.", nameof(serviceDefinition));
            }

            try
            {
                using (ServiceControlManager mgr = ServiceControlManager.Connect(nativeInterop, machineName
                                                                                 , databaseName, ServiceControlManagerAccessRights.All))
                {
                    if (mgr.TryOpenService(serviceDefinition.ServiceName
                                           , ServiceControlAccessRights.All
                                           , out ServiceHandle existingService
                                           , out System.ComponentModel.Win32Exception errorException)
                        )
                    {
                        using (existingService)
                        {
                            DoUpdateService(existingService, serviceDefinition, startImmediately);
                        }
                    }
                    else
                    {
                        if (errorException.NativeErrorCode == KnownWin32ErrorCoes.ERROR_SERVICE_DOES_NOT_EXIST)
                        {
                            DoCreateService(mgr, serviceDefinition, startImmediately);
                        }
                        else
                        {
                            throw errorException;
                        }
                    }
                }
예제 #4
0
        /// <summary>
        /// Installs the service.
        /// </summary>
        /// <param name="DisplayName">Service display name.</param>
        /// <param name="Description">Service description.</param>
        /// <param name="StartType">How the service should be started.</param>
        /// <param name="StartImmediately">If the service should be started immediately.</param>
        /// <param name="Credentials">Credentials to use when running service.</param>
        /// <returns>
        /// Return code:
        ///
        /// 0: Installed, not started.
        /// 1: Installed, started.
        /// 2: Updated, not started.
        /// 3: Updated, started.
        /// </returns>
        /// <exception cref="Exception">If service could not be installed.</exception>
        public int Install(string DisplayName, string Description, ServiceStartType StartType, bool StartImmediately, Win32ServiceCredentials Credentials)
        {
            string Path = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".exe");

            try
            {
                using (ServiceControlManager mgr = ServiceControlManager.Connect(null, null, ServiceControlManagerAccessRights.All))
                {
                    if (mgr.TryOpenService(this.serviceName, ServiceControlAccessRights.All, out ServiceHandle existingService,
                                           out Win32Exception errorException))
                    {
                        using (existingService)
                        {
                            existingService.ChangeConfig(DisplayName, Path, ServiceType.Win32OwnProcess,
                                                         StartType, ErrorSeverity.Normal, Credentials);

                            if (!string.IsNullOrEmpty(Description))
                            {
                                existingService.SetDescription(Description);
                            }

                            /*if (serviceFailureActions != null)
                             * {
                             *      existingService.SetFailureActions(serviceFailureActions);
                             *      existingService.SetFailureActionFlag(failureActionsOnNonCrashFailures);
                             * }*/

                            if (StartImmediately)
                            {
                                existingService.Start(throwIfAlreadyRunning: false);
                                return(3);
                            }
                            else
                            {
                                return(2);
                            }
                        }
                    }
                    else
                    {
                        if (errorException.NativeErrorCode == Win32.ERROR_SERVICE_DOES_NOT_EXIST)
                        {
                            using (ServiceHandle svc = mgr.CreateService(this.serviceName, DisplayName, Path, ServiceType.Win32OwnProcess,
                                                                         StartType, ErrorSeverity.Normal, Credentials))
                            {
                                if (!string.IsNullOrEmpty(Description))
                                {
                                    svc.SetDescription(Description);
                                }

                                /*if (serviceFailureActions != null)
                                 * {
                                 *      svc.SetFailureActions(serviceFailureActions);
                                 *      svc.SetFailureActionFlag(failureActionsOnNonCrashFailures);
                                 * }*/

                                if (StartImmediately)
                                {
                                    svc.Start();
                                    return(1);
                                }
                                else
                                {
                                    return(0);
                                }
                            }
                        }
                        else
                        {
                            throw errorException;
                        }
                    }
                }