Пример #1
0
 public static extern bool ChangeServiceConfig2(IntPtr hService,
                                                int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref SERVICE_DESCRIPTION lpInfo);
        ////////////////////////////////////////////////////////////////////////////////////
        // The worker method to set all the extension properties for the service

        private void UpdateServiceConfig(object sender, InstallEventArgs e)
        {

            // Determine if we need to set fail actions

            this.setFailActions = false;

            int numActions = FailureActions.Count;

            if (numActions > 0)
            {
                setFailActions = true;
            }

            // Do we need to do any work that the base installer did not do already?
            if (!(this.setDescription || this.setFailActions)) return;

            // We've got work to do
            IntPtr scmHndl = IntPtr.Zero;
            IntPtr svcHndl = IntPtr.Zero;
            IntPtr tmpBuf = IntPtr.Zero;
            IntPtr svcLock = IntPtr.Zero;

            // Err check var
            bool rslt = false;


            // Place all our code in a try block
            try
            {

                // Open the service control manager
                scmHndl = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);

                if (scmHndl.ToInt32() <= 0)
                {
                    LogInstallMessage(EventLogEntryType.Error, logMsgBase + "Failed to Open Service Control Manager");
                    return;
                }

                // Lock the Service Database
                svcLock = LockServiceDatabase(scmHndl);

                if (svcLock.ToInt32() <= 0)
                {

                    LogInstallMessage(EventLogEntryType.Error, logMsgBase + "Failed to Lock Service Database for Write");
                    return;
                }

                // Open the service
                svcHndl = OpenService(scmHndl, base.ServiceName, SERVICE_ALL_ACCESS);

                if (svcHndl.ToInt32() <= 0)
                {

                    LogInstallMessage(EventLogEntryType.Information, logMsgBase + "Failed to Open Service ");
                    return;
                }

                // Need to set service failure actions. Note that the API lets us set as many as
                // we want, yet the Service Control Manager GUI only lets us see the first 3.
                // Bill is aware of this and has promised no fixes. Also note that the API allows
                // granularity of seconds whereas GUI only shows days and minutes.

                if (this.setFailActions)
                {

                    // We're gonna serialize the SA_ACTION structs into an array of ints
                    // for simplicity in marshalling this variable length ptr to win32

                    int[] actions = new int[numActions * 2];

                    int currInd = 0;

                    bool needShutdownPrivilege = false;

                    foreach (FailureAction fa in FailureActions)
                    {

                        actions[currInd] = (int)fa.Type;
                        actions[++currInd] = fa.Delay;
                        currInd++;

                        if (fa.Type == RecoverAction.Reboot)
                        {
                            needShutdownPrivilege = true;
                        }

                    }

                    // If we need shutdown privilege, then grant it to this process
                    if (needShutdownPrivilege)
                    {

                        rslt = this.GrandShutdownPrivilege();

                        if (!rslt) return;

                    }

                    // Need to pack 8 bytes per struct
                    tmpBuf = Marshal.AllocHGlobal(numActions * 8);

                    // Move array into marshallable pointer
                    Marshal.Copy(actions, 0, tmpBuf, numActions * 2);

                    // Set the SERVICE_FAILURE_ACTIONS struct
                    SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();

                    sfa.cActions = numActions;
                    sfa.dwResetPeriod = this.failResetTime;
                    sfa.lpCommand = this.failRunCommand;
                    sfa.lpRebootMsg = this.failRebootMsg;
                    sfa.lpsaActions = tmpBuf.ToInt32();


                    // Call the ChangeServiceFailureActions() abstraction of ChangeServiceConfig2()
                    rslt = ChangeServiceFailureActions(svcHndl, SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa);

                    //Check the return
                    if (!rslt)
                    {

                        int err = Marshal.GetLastWin32Error();

                        if (err == ERROR_ACCESS_DENIED)
                        {
                            throw new Exception(logMsgBase + "Access Denied while setting Failure Actions");
                        }

                    }

                    // Free the memory
                    Marshal.FreeHGlobal(tmpBuf); tmpBuf = IntPtr.Zero;

                    LogInstallMessage(EventLogEntryType.Information, logMsgBase + "Successfully configured Failure Actions");

                }

                // Need to set the description field?
                if (this.setDescription)
                {

                    SERVICE_DESCRIPTION sd = new SERVICE_DESCRIPTION();
                    sd.lpDescription = this.description;

                    // Call the ChangeServiceDescription() abstraction of ChangeServiceConfig2()
                    rslt = ChangeServiceDescription(svcHndl, SERVICE_CONFIG_DESCRIPTION, ref sd);

                    // Error setting description?
                    if (!rslt)
                    {

                        throw new Exception(logMsgBase + "Failed to set description");

                    }

                    LogInstallMessage(EventLogEntryType.Information, logMsgBase + "Successfully set description");

                }

            }
            // Catch all exceptions
            catch (Exception ex)
            {
                ex.Trace();
            }
            finally
            {

                if (scmHndl != IntPtr.Zero)
                {

                    // Unlock the service database
                    if (svcLock != IntPtr.Zero)
                    {
                        UnlockServiceDatabase(svcLock);
                        svcLock = IntPtr.Zero;
                    }

                    // Close the service control manager handle
                    CloseServiceHandle(scmHndl);
                    scmHndl = IntPtr.Zero;
                }

                // Close the service handle
                if (svcHndl != IntPtr.Zero)
                {
                    CloseServiceHandle(svcHndl);
                    svcHndl = IntPtr.Zero;
                }

                // Free the memory
                if (tmpBuf != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(tmpBuf);
                    tmpBuf = IntPtr.Zero;
                }


            } // End try-catch-finally

        }
Пример #3
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);
        }
 public static extern bool ChangeServiceConfig2A(IntPtr hService, InfoLevel dwInfoLevel, ref SERVICE_DESCRIPTION lpInfo);
 public static partial bool ChangeServiceConfig2(SafeServiceHandle serviceHandle, uint infoLevel, ref SERVICE_DESCRIPTION serviceDesc);
Пример #6
0
 private static extern bool ChangeServiceConfig2(
     IntPtr hService,
     ServiceConfig dwInfoLevel,
     ref SERVICE_DESCRIPTION lpInfo);
 public static extern bool ChangeServiceConfig2(IntPtr serviceHandle, uint infoLevel, ref SERVICE_DESCRIPTION serviceDesc);
Пример #8
0
 ChangeServiceDescription(IntPtr hService, int dwInfoLevel,
                          [MarshalAs(UnmanagedType.Struct)] ref SERVICE_DESCRIPTION lpInfo);
Пример #9
0
        /// <summary>
        /// Installs the specified service name.
        /// </summary>
        /// <param name="serviceName">Name of the service.</param>
        /// <param name="displayName">The display name.</param>
        /// <param name="description">The description.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="userName">Name of the user.</param>
        /// <param name="password">The password.</param>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// </exception>
        public static void Install(
            [NotNull] string serviceName,
            [NotNull] string displayName,
            [NotNull] string description,
            [NotNull] string fileName,
            [CanBeNull] string userName = null,
            [CanBeNull] string password = null)
        {
            if (serviceName == null)
            {
                throw new ArgumentNullException("serviceName");
            }
            if (displayName == null)
            {
                throw new ArgumentNullException("displayName");
            }
            if (description == null)
            {
                throw new ArgumentNullException("description");
            }
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }

            if (ServiceIsInstalled(serviceName))
            {
                return;
            }

            IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);

            try
            {
                if (fileName.Contains(' '))
                {
                    fileName = string.Format("\"{0}\"", fileName);
                }

                IntPtr service = CreateService(
                    scm,
                    serviceName,
                    displayName,
                    ServiceAccessRights.AllAccess,
                    SERVICE_WIN32_OWN_PROCESS,
                    ServiceBootFlag.AutoStart,
                    ServiceError.Normal,
                    fileName,
                    null,
                    IntPtr.Zero,
                    null,
                    userName,
                    password);

                if (service == IntPtr.Zero)
                {
                    throw new CommonServiceException(
                              new Win32Exception(),
                              () => CommonResources.Err_ServiceUtils_Install_CouldNotInstallService,
                              serviceName);
                }
                try
                {
                    // Set description
                    SERVICE_DESCRIPTION sd = new SERVICE_DESCRIPTION
                    {
                        description = Marshal.StringToHGlobalUni(description)
                    };
                    try
                    {
                        bool flag = ChangeServiceConfig2(service, ServiceConfig.Description, ref sd);
                        if (!flag)
                        {
                            throw new CommonServiceException(
                                      new Win32Exception(),
                                      () => CommonResources.Err_ServiceUtils_Install_CouldNotSetDescription,
                                      serviceName);
                        }
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(sd.description);
                    }
                }
                finally
                {
                    CloseServiceHandle(service);
                }
            }
            finally
            {
                CloseServiceHandle(scm);
            }
        }
Пример #10
0
 private static extern int ChangeServiceConfig2(IntPtr hService, int dwServiceConfigDescription, ref SERVICE_DESCRIPTION lpInfo);
Пример #11
0
 public static extern bool ChangeServiceConfigDescription(
     IntPtr hService,
     uint dwInfoLevel,
     ref SERVICE_DESCRIPTION lpInfo);
Пример #12
0
 private static extern bool ChangeServiceConfig2(IntPtr hService, int dwInfoLevel, ref SERVICE_DESCRIPTION lpDescription);
Пример #13
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;
        }
        /// <summary>
        /// This method installs and runs the service in the service control manager.
        /// </summary>
        /// <param name="svcPath">The complete path of the service.</param>
        /// <param name="svcName">Name of the service.</param>
        /// <param name="svcDispName">Display name of the service.</param>
        /// <param name="svcDescription">The English description of the service.</param>
        /// <param name="svcStartType">The start type of the service (automatic, manual, etc)</param>
        /// <returns>True if the process went thro successfully. False if there was any error.</returns>
        public bool InstallService(string svcPath, string svcName, string svcDispName, string svcDescription, SERVICE_START_TYPE svcStartType, string dependencies)
        {
            var bSuccess = false;

            #region Constants declaration.

            int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
            int SERVICE_INTERACTIVE_PROCESS = 0x00000100;
            int SERVICE_ERROR_NORMAL = 0x00000001;

            int STANDARD_RIGHTS_REQUIRED = 0xF0000;
            int SERVICE_QUERY_CONFIG = 0x0001;
            int SERVICE_CHANGE_CONFIG = 0x0002;
            int SERVICE_QUERY_STATUS = 0x0004;
            int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
            int SERVICE_START = 0x0010;
            int SERVICE_STOP = 0x0020;
            int SERVICE_PAUSE_CONTINUE = 0x0040;
            int SERVICE_INTERROGATE = 0x0080;
            int SERVICE_USER_DEFINED_CONTROL = 0x0100;

            int SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
                SERVICE_QUERY_CONFIG |
                SERVICE_CHANGE_CONFIG |
                SERVICE_QUERY_STATUS |
                SERVICE_ENUMERATE_DEPENDENTS |
                SERVICE_START |
                SERVICE_STOP |
                SERVICE_PAUSE_CONTINUE |
                SERVICE_INTERROGATE |
                SERVICE_USER_DEFINED_CONTROL);

            #endregion Constants declaration.

            try
            {
                var hServiceCtrlMgr = OpenSCManager(null, null, SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
                var servDesc = new SERVICE_DESCRIPTION()
                    {
                        lpDescription = svcDescription
                    };

                if (hServiceCtrlMgr.ToInt32() != 0)
                {
                    IntPtr hService = CreateService(hServiceCtrlMgr, svcName, svcDispName,
                                                        SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
                                                        svcStartType, SERVICE_ERROR_NORMAL,
                                                        svcPath, null, 0, dependencies, null, null);

                    if (hService.ToInt32() == 0)
                    {
                        CloseServiceHandle(hServiceCtrlMgr);
                        throw new Exception("Unable to start the service due to some error.  Is the service already running?");
                    }
                    else
                    {
                        //  Add the description to the service
                        bSuccess = ChangeServiceConfig2A(hService, InfoLevel.SERVICE_CONFIG_DESCRIPTION, ref servDesc);

                        //  Now trying to start the service
                        int nStartSuccess = StartService(hService, 0, null);

                        //  If the value i is zero, then there was an error starting the service.
                        //  NOTE: error may arise if the service is already running or some other problem.
                        if (nStartSuccess != 0)
                        {
                            CloseServiceHandle(hServiceCtrlMgr);
                            bSuccess = true;
                        }
                        else
                            throw new Exception("Unable to start the service due to some error.  Is the service already running?");
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex);
            }

            return bSuccess;
        }
Пример #15
0
 public static extern bool ChangeServiceConfig2(IntPtr serviceHandle, uint infoLevel, ref SERVICE_DESCRIPTION serviceDesc);
Пример #16
0
 private static extern bool ChangeServiceConfig2(
     IntPtr hService,
     ServiceConfig dwInfoLevel,
     ref SERVICE_DESCRIPTION lpInfo);
Пример #17
0
        /// <summary>
        /// Installs the specified service name.
        /// </summary>
        /// <param name="serviceName">Name of the service.</param>
        /// <param name="displayName">The display name.</param>
        /// <param name="description">The description.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="userName">Name of the user.</param>
        /// <param name="password">The password.</param>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// </exception>
        public static void Install(
            [NotNull] string serviceName,
            [NotNull] string displayName,
            [NotNull] string description,
            [NotNull] string fileName,
            [CanBeNull] string userName = null,
            [CanBeNull] string password = null)
        {
            if (serviceName == null) throw new ArgumentNullException("serviceName");
            if (displayName == null) throw new ArgumentNullException("displayName");
            if (description == null) throw new ArgumentNullException("description");
            if (fileName == null) throw new ArgumentNullException("fileName");

            if (ServiceIsInstalled(serviceName))
                return;

            IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);
            try
            {
                if (fileName.Contains(' '))
                    fileName = string.Format("\"{0}\"", fileName);

                IntPtr service = CreateService(
                    scm,
                    serviceName,
                    displayName,
                    ServiceAccessRights.AllAccess,
                    SERVICE_WIN32_OWN_PROCESS,
                    ServiceBootFlag.AutoStart,
                    ServiceError.Normal,
                    fileName,
                    null,
                    IntPtr.Zero,
                    null,
                    userName,
                    password);

                if (service == IntPtr.Zero)
                    throw new CommonServiceException(
                        new Win32Exception(),
                        () => CommonResources.Err_ServiceUtils_Install_CouldNotInstallService,
                        serviceName);
                try
                {
                    // Set description
                    SERVICE_DESCRIPTION sd = new SERVICE_DESCRIPTION
                    {
                        description = Marshal.StringToHGlobalUni(description)
                    };
                    try
                    {
                        bool flag = ChangeServiceConfig2(service, ServiceConfig.Description, ref sd);
                        if (!flag)
                            throw new CommonServiceException(
                                new Win32Exception(),
                                () => CommonResources.Err_ServiceUtils_Install_CouldNotSetDescription,
                                serviceName);
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(sd.description);
                    }
                }
                finally
                {
                    CloseServiceHandle(service);
                }
            }
            finally
            {
                CloseServiceHandle(scm);
            }
        }
Пример #18
0
    public static void Install(string serviceName, string displayName, string fileName, ServiceBootFlag startFlag = ServiceBootFlag.AutoStart, string description = null)
    {
      var scm = OpenSCManager(ScmAccessRights.AllAccess);

      try
      {
        var service = OpenService(scm, serviceName, ServiceAccessRights.AllAccess);

        if (service == IntPtr.Zero)
          service = CreateService(scm, serviceName, displayName, ServiceAccessRights.AllAccess, SERVICE_WIN32_OWN_PROCESS, 
            startFlag, ServiceError.Normal, fileName, null, IntPtr.Zero, null, null, null);

        if (service == IntPtr.Zero)
          throw new ApplicationException("Failed to install service.");

        if (!string.IsNullOrEmpty(description))
        {
          var serviceDescription = new SERVICE_DESCRIPTION { lpDescription = Marshal.StringToHGlobalAnsi(description) };
          ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, ref serviceDescription);
          Marshal.FreeHGlobal(serviceDescription.lpDescription);
        }

        CloseServiceHandle(service);
      }
      finally
      {
        CloseServiceHandle(scm);
      }
    }
        /// <summary>
        /// Update installed service's config accordinly.
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">event args</param>
        private void UpdateServiceConfig(object sender, InstallEventArgs e)
        {
            IntPtr scmHndl = IntPtr.Zero;
            IntPtr svcHndl = IntPtr.Zero;
            IntPtr tmpBuf = IntPtr.Zero;
            IntPtr svcLock = IntPtr.Zero;

            try
            {
                // Open the service control manager
                scmHndl = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
                if (scmHndl.ToInt32() <= 0)
                {
                    LogInstallMessage(EventLogEntryType.Error,
                        "Failed to Open Service Control Manager");
                    return;
                }

                // Lock the Service Database
                svcLock = LockServiceDatabase(scmHndl);
                if (svcLock.ToInt32() <= 0)
                {
                    LogInstallMessage(EventLogEntryType.Error,
                        "Failed to Lock Service Database for Write");
                    return;
                }

                // Open the service
                svcHndl = OpenService(scmHndl, ServiceName, SERVICE_ALL_ACCESS);
                if (svcHndl.ToInt32() <= 0)
                {
                    LogInstallMessage(EventLogEntryType.Information,
                        "Failed to Open Service ");
                    return;
                }

                // Need to set service failure actions. Note that the API lets us set as many as
                // we want, yet the Service Control Manager GUI only lets us see the first 3.
                // Also note that the API allows granularity of seconds whereas GUI only shows days and minutes.
                if (FailureActions.Count > 0)
                {
                    int[] actions = new int[FailureActions.Count * 2];
                    int i = 0;
                    bool needShutdownPrivilege = false;
                    foreach (FailureAction fa in FailureActions)
                    {
                        actions[i] = (int)fa.Type;
                        actions[++i] = fa.DelaySeconds * 1000;
                        i++;
                        if (fa.Type == FailureActionType.Reboot)
                        {
                            needShutdownPrivilege = true;
                        }
                    }
                    // If we need shutdown privilege, then grant it to this process
                    if (needShutdownPrivilege)
                    {
                        GrantShutdownPrivilege();
                    }

                    tmpBuf = Marshal.AllocHGlobal(FailureActions.Count * 8);
                    Marshal.Copy(actions, 0, tmpBuf, FailureActions.Count * 2);
                    SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();
                    sfa.cActions = FailureActions.Count;
                    sfa.dwResetPeriod = FailCountResetTime;
                    if (FailureCommandAction != null)
                    {
                        sfa.lpCommand = FailureCommandAction.ToString();
                    }
                    sfa.lpRebootMsg = FailureRebootMessage;
                    sfa.lpsaActions = tmpBuf.ToInt32();

                    SERVICE_FAILURE_ACTIONS_FLAG sfaf = new SERVICE_FAILURE_ACTIONS_FLAG();
                    sfaf.bFailureAction = true;
                    if (!ChangeServiceFailureActionFlag(svcHndl, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, ref sfaf))
                    {
                        throw new Win32Exception(GetLastError());
                    }

                    if (!ChangeServiceFailureActions(svcHndl, SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa))
                    {
                        if (GetLastError() == ERROR_ACCESS_DENIED)
                        {
                            throw new Exception(
                                "Access Denied while setting Failure Actions");
                        }
                    }

                    Marshal.FreeHGlobal(tmpBuf); tmpBuf = IntPtr.Zero;
                    LogInstallMessage(EventLogEntryType.Information,
                        "Successfully configured Failure Actions");
                }

                if (Description != null && Description.Length > 0)
                {
                    SERVICE_DESCRIPTION sd = new SERVICE_DESCRIPTION();
                    sd.lpDescription = Description;
                    if (!ChangeServiceDescription(svcHndl, SERVICE_CONFIG_DESCRIPTION, ref sd))
                    {
                        throw new Exception("Failed to set description");
                    }
                    LogInstallMessage(EventLogEntryType.Information,
                        "Successfully set description");
                }
            }
            catch (Exception ex)
            {
                LogInstallMessage(EventLogEntryType.Error, Format(ex));
            }
            finally
            {
                if (scmHndl != IntPtr.Zero)
                {
                    // Unlock the service database
                    if (svcLock != IntPtr.Zero)
                    {
                        UnlockServiceDatabase(svcLock);
                        svcLock = IntPtr.Zero;
                    }
                    CloseServiceHandle(scmHndl);
                    scmHndl = IntPtr.Zero;
                }
                // Close the service handle
                if (svcHndl != IntPtr.Zero)
                {
                    CloseServiceHandle(svcHndl);
                    svcHndl = IntPtr.Zero;
                }
                // Free the memory
                if (tmpBuf != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(tmpBuf);
                    tmpBuf = IntPtr.Zero;
                }
            }
        }
Пример #20
0
 private static extern int ChangeServiceConfig2(IntPtr hService, uint dwInfoLevel, ref SERVICE_DESCRIPTION info);
        ////////////////////////////////////////////////////////////////////////////////////
        // The worker method to set all the extension properties for the service

        public void UpdateServiceConfig(object sender, InstallEventArgs e)
        {
            // Determine if we need to set fail actions

            this.setFailActions = false;

            int numActions = FailureActions.Count;

            if (numActions > 0)
            {
                setFailActions = true;
            }

            // Do we need to do any work that the base installer did not do already?
            if (!(this.setDescription || this.setFailActions))
            {
                return;
            }

            // We've got work to do
            IntPtr scmHndl = IntPtr.Zero;
            IntPtr svcHndl = IntPtr.Zero;
            IntPtr tmpBuf  = IntPtr.Zero;
            IntPtr svcLock = IntPtr.Zero;

            // Err check var
            bool rslt = false;


            // Place all our code in a try block
            try {
                // Open the service control manager
                scmHndl = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);

                if (scmHndl.ToInt32() <= 0)
                {
                    LogInstallMessage(EventLogEntryType.Error, logMsgBase + "Failed to Open Service Control Manager");
                    return;
                }

                // Lock the Service Database
                svcLock = LockServiceDatabase(scmHndl);

                if (svcLock.ToInt32() <= 0)
                {
                    LogInstallMessage(EventLogEntryType.Error, logMsgBase + "Failed to Lock Service Database for Write");
                    return;
                }

                // Open the service
                svcHndl = OpenService(scmHndl, base.ServiceName, SERVICE_ALL_ACCESS);

                if (svcHndl.ToInt32() <= 0)
                {
                    LogInstallMessage(EventLogEntryType.Information, logMsgBase + "Failed to Open Service ");
                    return;
                }

                // Need to set service failure actions. Note that the API lets us set as many as
                // we want, yet the Service Control Manager GUI only lets us see the first 3.
                // Bill is aware of this and has promised no fixes. Also note that the API allows
                // granularity of seconds whereas GUI only shows days and minutes.

                if (this.setFailActions)
                {
                    // We're gonna serialize the SA_ACTION structs into an array of ints
                    // for simplicity in marshalling this variable length ptr to win32

                    int[] actions = new int[numActions * 2];

                    int currInd = 0;

                    bool needShutdownPrivilege = false;

                    foreach (FailureAction fa in FailureActions)
                    {
                        actions[currInd]   = (int)fa.Type;
                        actions[++currInd] = fa.Delay;
                        currInd++;

                        if (fa.Type == RecoverAction.Reboot)
                        {
                            needShutdownPrivilege = true;
                        }
                    }

                    // If we need shutdown privilege, then grant it to this process
                    if (needShutdownPrivilege)
                    {
                        rslt = this.GrandShutdownPrivilege();

                        if (!rslt)
                        {
                            return;
                        }
                    }

                    // Need to pack 8 bytes per struct
                    tmpBuf = Marshal.AllocHGlobal(numActions * 8);

                    // Move array into marshallable pointer
                    Marshal.Copy(actions, 0, tmpBuf, numActions * 2);

                    // Set the SERVICE_FAILURE_ACTIONS struct
                    SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();

                    sfa.cActions      = numActions;
                    sfa.dwResetPeriod = this.failResetTime;
                    sfa.lpCommand     = this.failRunCommand;
                    sfa.lpRebootMsg   = this.failRebootMsg;
                    sfa.lpsaActions   = tmpBuf.ToInt32();


                    // Call the ChangeServiceFailureActions() abstraction of ChangeServiceConfig2()
                    rslt = ChangeServiceFailureActions(svcHndl, SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa);

                    //Check the return
                    if (!rslt)
                    {
                        int err = GetLastError();

                        if (err == ERROR_ACCESS_DENIED)
                        {
                            throw new Exception(logMsgBase + "Access Denied while setting Failure Actions");
                        }
                    }

                    // Free the memory
                    Marshal.FreeHGlobal(tmpBuf); tmpBuf = IntPtr.Zero;

                    LogInstallMessage(EventLogEntryType.Information, logMsgBase + "Successfully configured Failure Actions");
                }

                // Need to set the description field?
                if (this.setDescription)
                {
                    SERVICE_DESCRIPTION sd = new SERVICE_DESCRIPTION();
                    sd.lpDescription = this.description;

                    // Call the ChangeServiceDescription() abstraction of ChangeServiceConfig2()
                    rslt = ChangeServiceDescription(svcHndl, SERVICE_CONFIG_DESCRIPTION, ref sd);

                    // Error setting description?
                    if (!rslt)
                    {
                        throw new Exception(logMsgBase + "Failed to set description");
                    }

                    LogInstallMessage(EventLogEntryType.Information, logMsgBase + "Successfully set description");
                }
            }
            // Catch all exceptions
            catch (Exception ex) {
                LogInstallMessage(EventLogEntryType.Error, ex.Message);
            }
            finally{
                if (scmHndl != IntPtr.Zero)
                {
                    // Unlock the service database
                    if (svcLock != IntPtr.Zero)
                    {
                        UnlockServiceDatabase(svcLock);
                        svcLock = IntPtr.Zero;
                    }

                    // Close the service control manager handle
                    CloseServiceHandle(scmHndl);
                    scmHndl = IntPtr.Zero;
                }

                // Close the service handle
                if (svcHndl != IntPtr.Zero)
                {
                    CloseServiceHandle(svcHndl);
                    svcHndl = IntPtr.Zero;
                }

                // Free the memory
                if (tmpBuf != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(tmpBuf);
                    tmpBuf = IntPtr.Zero;
                }
            }             // End try-catch-finally
        }
Пример #22
-1
        public static unsafe void SetServiceDescription( String name, String description)
        {
            // prepare
            byte *_name = stackalloc byte[ name.Length];
            byte *_desc = stackalloc byte[ description.Length];
            char[] cname = name.ToCharArray();
            char[] cdesc = description.ToCharArray();
            // copy the name
            for( int i = 0; i < name.Length; i++) _name[i] = (byte)cname[i];
            _name[ name.Length] = 0;
            for( int i = 0; i < description.Length; i++) _desc[i] = (byte)cdesc[i];
            _desc[ description.Length] = 0;

            IntPtr srvName = new IntPtr( _name);
            SERVICE_DESCRIPTION info = new SERVICE_DESCRIPTION();
            info.description = new IntPtr( _desc);

            // open the SC manager db
            IntPtr scHandle = Win32_OpenSCManager( new IntPtr(null),  new IntPtr(null),
                                STANDARD_RIGHTS_REQUIRED |
                                SC_MANAGER_CONNECT |
                                SC_MANAGER_CREATE_SERVICE |
                                SC_MANAGER_ENUMERATE_SERVICE |
                                SC_MANAGER_LOCK |
                                SC_MANAGER_QUERY_LOCK_STATUS |
                                SC_MANAGER_MODIFY_BOOT_CONFIG );
            // open the service
            IntPtr srvHandle = Win32_OpenService( scHandle, srvName, SERVICE_CHANGE_CONFIG);
            // set service description
            Win32_ChangeServiceConfig2( srvHandle, SERVICE_CONFIG_DESCRIPTION, new IntPtr( &info));
            // close service
            Win32_CloseService( srvHandle);
            // close SC manager db
        }