Provides functionalities to manage Windows services such as Start/Stop service.
Example #1
0
        /// <summary>
        /// Installs and optionally starts the service.
        /// </summary>
        /// <param name="path">The full path of the service exe.</param>
        /// <param name="name">The name of the service.</param>
        /// <param name="displayName">The display name of the service.</param>
        /// <param name="description">The description for the service.</param>
        /// <param name="startMode">The service start mode.</param>
        /// <param name="userName">The account name. Null to use the default account (LocalSystem).</param>
        /// <param name="password">The account password.</param>
        /// <param name="start">True to start the service after the installation; otherwise, false.
        /// Once the method returns you can use this parameter to check whether the service is running or not.</param>
        /// <param name="dependencies">The list of dependencies services. Null if there are no dependencies.</param>
        /// <returns>True for success. Otherwise, false.</returns>
        public static bool InstallService(
            string path,
            string name,
            string displayName,
            string description,
            StartMode startMode,
            string userName,
            string password,
            ref bool start,
            string[]  dependencies)
        {
            uint SC_MANAGER_CREATE_SERVICE = 0x0002;

            if (string.IsNullOrEmpty(userName))
            {
                userName = null;
                password = null;
            }

            // check if an existing service needs to uninstalled.
            try
            {
                Service existingService = ServiceManager.GetService(name);

                if (existingService != null)
                {
                    if (existingService.StartMode != StartMode.Disabled && existingService.Path == path)
                    {
                        if (existingService.Status == ServiceStatus.Stopped)
                        {
                            ServiceManager.StartService(name);
                        }

                        return(true);
                    }

                    UnInstallService(name);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "CreateService Exception");
            }

            IntPtr svHandle = IntPtr.Zero;

            try
            {
                IntPtr scHandle = OpenSCManagerW(null, null, SC_MANAGER_CREATE_SERVICE);

                if (scHandle.ToInt64() != 0)
                {
                    string dependencyServices = string.Empty;

                    if (dependencies != null && dependencies.Length > 0)
                    {
                        for (int i = 0; i < dependencies.Length; i++)
                        {
                            if (!string.IsNullOrEmpty(dependencies[i]))
                            {
                                dependencyServices += dependencies[i].Trim();
                                if (i < dependencies.Length - 1)
                                {
                                    dependencyServices += "\0";//add a null char separator
                                }
                            }
                        }
                    }

                    if (dependencyServices == string.Empty)
                    {
                        dependencyServices = null;
                    }

                    // lpDependencies, if not null, must be a series of strings concatenated with the null character as a delimiter, including a trailing one.

                    svHandle = CreateServiceW(
                        scHandle,
                        name,
                        displayName,
                        (uint)ServiceAccess.AllAccess,
                        (uint)ServiceType.OwnProcess,
                        (uint)startMode,
                        (uint)ServiceError.ErrorNormal,
                        path,
                        null,
                        0,
                        dependencyServices,
                        userName,
                        password);

                    if (svHandle.ToInt64() == 0)
                    {
                        int error = GetLastError();
                        Utils.Trace("CreateService Error: {0}", error);
                        return(false);
                    }

                    // set the description.
                    if (!String.IsNullOrEmpty(description))
                    {
                        SERVICE_DESCRIPTION info = new SERVICE_DESCRIPTION();
                        info.lpDescription = description;

                        IntPtr pInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(SERVICE_DESCRIPTION)));
                        Marshal.StructureToPtr(info, pInfo, false);

                        try
                        {
                            int result = ChangeServiceConfig2W(svHandle, SERVICE_CONFIG_DESCRIPTION, pInfo);

                            if (result == 0)
                            {
                                Utils.Trace("Could not set description for service: {0}", displayName);
                            }
                        }
                        finally
                        {
                            Marshal.DestroyStructure(pInfo, typeof(SERVICE_DESCRIPTION));
                            Marshal.FreeCoTaskMem(pInfo);
                        }
                    }

                    // start the service.
                    if (start)
                    {
                        start = ServiceManager.StartService(name, new TimeSpan(0, 0, 0, 60));
                    }

                    return(true);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "CreateService Exception");
            }
            finally
            {
                SafeCloseServiceHandle(svHandle);
            }

            return(false);
        }