Пример #1
0
        public static void Install(string path, string username, string password)
        {
            try
            {
                logger.Info($"Opening service control manager");
                var      serviceManager = AdvApi32.OpenSCManager(null, null, AdvApi32.ScManagerAccessTypes.SC_MANAGER_ALL_ACCESS);
                string[] dependencies   = new[] { "http" };
                logger.Info($"Opened service control manager");
                AdvApi32.SafeSC_HANDLE serviceHandle;

                if (!path.StartsWith("\""))
                {
                    path = "\"" + path;
                }

                if (!path.EndsWith("\""))
                {
                    path = path + "\"";
                }

                try
                {
                    logger.Info($"Checking for existing {Constants.ServiceName} service");
                    serviceHandle = AdvApi32.OpenService(serviceManager, Constants.ServiceName, AdvApi32.ServiceAccessTypes.SERVICE_ALL_ACCESS);

                    if (serviceHandle.IsNull)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    logger.Info($"Found existing {Constants.ServiceName} service");
                }
                catch (Win32Exception ex)
                {
                    if (ex.NativeErrorCode == 1060)
                    {
                        logger.Info($"Existing {Constants.ServiceName} service not found");
                        logger.Info($"Attempting to create server {Constants.ServiceName} for user {username} at {path}");

                        serviceHandle = AdvApi32.CreateService(serviceManager, Constants.ServiceName, Constants.ServiceDisplayName, (uint)AdvApi32.ServiceAccessTypes.SERVICE_ALL_ACCESS, AdvApi32.ServiceTypes.SERVICE_WIN32_OWN_PROCESS, AdvApi32.ServiceStartType.SERVICE_DEMAND_START, AdvApi32.ServiceErrorControlType.SERVICE_ERROR_NORMAL, path, null, IntPtr.Zero, dependencies, username, password);

                        if (serviceHandle.IsNull)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        logger.Info($"Created {Constants.ServiceName} service");
                    }
                    else
                    {
                        throw;
                    }
                }

                var description = new AdvApi32.SERVICE_DESCRIPTION()
                {
                    lpDescription = Constants.ServiceDescription
                };

                logger.Info($"Updating service description");
                if (!AdvApi32.ChangeServiceConfig2(serviceHandle, AdvApi32.ServiceConfigOption.SERVICE_CONFIG_DESCRIPTION, description))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var sidConfig = new AdvApi32.SERVICE_SID_INFO()
                {
                    dwServiceSidType = 0x1
                };

                logger.Info($"Updating service SID configuration");
                if (!AdvApi32.ChangeServiceConfig2(serviceHandle, AdvApi32.ServiceConfigOption.SERVICE_CONFIG_SERVICE_SID_INFO, sidConfig))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                logger.Info($"Updated existing {Constants.ServiceName} service parameters");

                TryGrantLogonAsAService(username);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Unable to install service");
                throw;
            }
        }