Example #1
0
        public static NativeMethods.ServiceStatusInfo ReadServiceStatus(SafeServiceHandle serviceHandle)
        {
            NativeMethods.ServiceStatusInfo ServiceStatus = default;

            if (!NativeMethods.QueryServiceStatus(serviceHandle, ref ServiceStatus))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return(ServiceStatus);
        }
Example #2
0
 public static extern bool ChangeServiceConfig(
     SafeServiceHandle hService,
     uint dwServiceType,
     uint dwStartType,
     uint dwErrorControl,
     string?lpBinaryPathName,
     string?lpLoadOrderGroup,
     IntPtr lpdwTagId,
     string?lpDependencies,
     string?lpServiceStartName,
     IntPtr lpPassword,
     string?lpDisplayName);
Example #3
0
        /// <summary>
        /// Starts a service.
        /// </summary>
        /// <param name="arguments">An array of arguments to pass to the service when it starts.</param>
        public void Start(string?[]?arguments)
        {
            arguments ??= Array.Empty <string>();

            using SafeServiceHandle ServiceManager = ServiceHelper.OpenServiceManager(
                      MachineName,
                      NativeMethods.SC_MANAGER_CONNECT);

            using SafeServiceHandle ServiceHandle = ServiceHelper.OpenService(
                      ServiceManager,
                      ServiceName,
                      NativeMethods.SERVICE_START);

            IntPtr[] ArumentPointers = new IntPtr[arguments.Length];
            int      ArgumentIndex   = 0;

            try
            {
                for (ArgumentIndex = 0; ArgumentIndex < arguments.Length; ArgumentIndex++)
                {
                    if (arguments[ArgumentIndex] == null)
                    {
                        throw new ArgumentException($"Argument at index {ArgumentIndex} is null which cannot be passed to sevice.", nameof(arguments));
                    }
                    ArumentPointers[ArgumentIndex] = Marshal.StringToHGlobalUni(arguments[ArgumentIndex]);
                }

                GCHandle gcHandle = GCHandle.Alloc(ArumentPointers, GCHandleType.Pinned);
                try
                {
                    if (!NativeMethods.StartService(ServiceHandle, (uint)arguments.Length, gcHandle.AddrOfPinnedObject()))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                finally
                {
                    if (gcHandle.IsAllocated)
                    {
                        gcHandle.Free();
                    }
                }
            }
            finally
            {
                for (int i = 0; i < ArgumentIndex; i++)
                {
                    Marshal.FreeHGlobal(ArumentPointers[i]);
                }
            }
        }
Example #4
0
 public static extern SafeServiceHandle CreateService(
     SafeServiceHandle hSCManager,
     string lpServiceName,
     string lpDisplayName,
     uint dwDesiredAccess,
     uint dwServiceType,
     uint dwStartType,
     uint dwErrorControl,
     string lpBinaryPathName,
     string?lpLoadOrderGroup,
     IntPtr lpdwTagId,
     string?lpDependencies,
     string?lpServiceStartName,
     IntPtr lpPassword);
Example #5
0
        /// <summary>
        /// Deletes a service.
        /// </summary>
        public void Delete()
        {
            using SafeServiceHandle ServiceManager = ServiceHelper.OpenServiceManager(
                      MachineName,
                      NativeMethods.SC_MANAGER_CONNECT);

            using SafeServiceHandle ServiceHandle = ServiceHelper.OpenService(
                      ServiceManager,
                      ServiceName,
                      NativeMethods.DELETE);

            if (!NativeMethods.DeleteService(ServiceHandle))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
Example #6
0
        public static IEnumerable <Service> FindServices(string machineName)
        {
            using SafeServiceHandle ServiceManager = OpenServiceManager(machineName, NativeMethods.SC_MANAGER_ENUMERATE_SERVICE);

            uint ResumeHandle = 0;

            NativeMethods.EnumServicesStatus(ServiceManager, NativeMethods.SERVICE_WIN32, NativeMethods.SERVICE_STATE_ALL, IntPtr.Zero, 0, out uint BytesNeeded, out uint ServicesReturned, ref ResumeHandle);

            int ErrorCode = Marshal.GetLastWin32Error();

            if (ErrorCode != NativeMethods.ERROR_MORE_DATA)
            {
                throw new Win32Exception(ErrorCode);
            }

            IntPtr ptr = Marshal.AllocHGlobal((int)BytesNeeded);

            try
            {
                if (!NativeMethods.EnumServicesStatus(ServiceManager, NativeMethods.SERVICE_WIN32, NativeMethods.SERVICE_STATE_ALL, ptr, BytesNeeded, out BytesNeeded, out ServicesReturned, ref ResumeHandle))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                Collection <Service> Status = new Collection <Service>();

                for (int index = 0; index < ServicesReturned; ++index)
                {
                    IntPtr itemPtr = (IntPtr)((long)ptr + (index * NativeMethods.EnumServiceStatusInfo.SizeOf));
                    NativeMethods.EnumServiceStatusInfo EnumServiceStatus = new NativeMethods.EnumServiceStatusInfo();
                    Marshal.PtrToStructure(itemPtr, EnumServiceStatus);

                    Status.Add(new Service(
                                   machineName,
                                   EnumServiceStatus.lpServiceName ?? string.Empty,
                                   EnumServiceStatus.lpDisplayName ?? string.Empty,
                                   EnumServiceStatus.ServiceStatus.dwCurrentState));
                }

                return(Status);
            }
            finally
            {
                Marshal.FreeHGlobal(ptr);
            }
        }
Example #7
0
        private void ControlService(uint dwAccess, uint dwControl)
        {
            using SafeServiceHandle ServiceManager = ServiceHelper.OpenServiceManager(
                      MachineName,
                      NativeMethods.SC_MANAGER_CONNECT);

            using SafeServiceHandle ServiceHandle = ServiceHelper.OpenService(
                      ServiceManager,
                      ServiceName,
                      dwAccess);

            NativeMethods.ServiceStatusInfo Status = default;

            if (!NativeMethods.ControlService(ServiceHandle, dwControl, ref Status))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            State = Status.dwCurrentState;
        }
Example #8
0
 public static extern SafeServiceHandle OpenService(
     SafeServiceHandle hSCManager,
     string lpServiceName,
     uint dwDesiredAccess);
Example #9
0
 public static extern bool QueryServiceStatus(SafeServiceHandle hService, ref ServiceStatusInfo lpServiceStatus);
Example #10
0
        private static NativeMethods.ServiceConfigurationInfo ReadServiceConfiguration(SafeServiceHandle serviceHandle)
        {
            NativeMethods.QueryServiceConfig(serviceHandle, IntPtr.Zero, 0, out uint BytesNeeded);

            int ErrorCode = Marshal.GetLastWin32Error();

            if (ErrorCode != NativeMethods.ERROR_INSUFFICIENT_BUFFER)
            {
                throw new Win32Exception(ErrorCode);
            }

            IntPtr ptr = Marshal.AllocHGlobal((int)BytesNeeded);

            try
            {
                if (!NativeMethods.QueryServiceConfig(serviceHandle, ptr, BytesNeeded, out BytesNeeded))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                NativeMethods.ServiceConfigurationInfo ServiceConfiguration = new NativeMethods.ServiceConfigurationInfo();

                Marshal.PtrToStructure(ptr, ServiceConfiguration);

                return(ServiceConfiguration);
            }
            finally
            {
                Marshal.FreeHGlobal(ptr);
            }
        }
Example #11
0
 public static extern bool QueryServiceConfig(SafeServiceHandle hService, IntPtr lpServiceConfig, uint cbBufSize, out uint pcbBytesNeeded);
Example #12
0
 public static extern bool QueryServiceConfig2(SafeServiceHandle hService, uint dwInfoLevel, IntPtr lpBuffer, uint cbBufSize, out uint pcbBytesNeeded);
Example #13
0
 public static extern bool ControlService(
     SafeServiceHandle hService,
     uint dwControl,
     ref ServiceStatusInfo lpServiceStatus);
Example #14
0
 public static extern bool StartService(SafeServiceHandle hService, uint dwNumServiceArgs, IntPtr lpServiceArgVectors);
Example #15
0
        public static (ServiceConfiguration ServiceConfiguration, string BinaryPath) ReadServiceConfiguration(SafeServiceHandle serviceHandle, string serviceName)
        {
            NativeMethods.ServiceConfigurationInfo ServiceConfiguration = ReadServiceConfiguration(serviceHandle);

            (ServiceAccount Account, string?Username) = ServiceController.ConvertWindowsUsernameToServiceConfiguration(ServiceConfiguration.lpServiceStartName);

            ServiceStartMode StartMode = ReadServiceDelayedAutoStartConfiguration(serviceHandle)
                                ? ServiceStartMode.AutomaticDelayedStart
                                : (ServiceStartMode)ServiceConfiguration.dwStartType;

            return(
                new ServiceConfiguration
            {
                ServiceName = serviceName,
                DisplayName = ServiceConfiguration.lpDisplayName,
                Description = ReadServiceDescription(serviceHandle),
                StartMode = StartMode,
                Account = Account,
                Username = Username
            },
                ServiceConfiguration.lpBinaryPathName ?? string.Empty);
        }
Example #16
0
        /// <summary>
        /// Configure a service.
        /// </summary>
        /// <param name="displayName"><see cref="ServiceConfiguration.DisplayName"/>.</param>
        /// <param name="description"><see cref="ServiceConfiguration.Description"/>.</param>
        /// <param name="startMode"><see cref="ServiceConfiguration.StartMode"/>.</param>
        /// <param name="account"><see cref="ServiceConfiguration.Account"/>.</param>
        /// <param name="username"><see cref="ServiceConfiguration.Username"/>.</param>
        /// <param name="password"><see cref="ServiceConfiguration.Password"/>.</param>
        /// <param name="binaryPathAndArguments">The fully qualified path to the service binary file optionally including arguments to be passed when starting the service. Specify null to leave the current value unchanged.</param>
        public void Configure(
            string?displayName,
            string?description,
            ServiceStartMode startMode,
            ServiceAccount account,
            string?username,
            SecureString?password,
            string?binaryPathAndArguments = null)
        {
            string DisplayName = string.IsNullOrEmpty(displayName)
                                ? ServiceName
                                : displayName;

            using SafeServiceHandle ServiceManager = ServiceHelper.OpenServiceManager(
                      MachineName,
                      NativeMethods.SC_MANAGER_CONNECT);

            using SafeServiceHandle ServiceHandle = ServiceHelper.OpenService(
                      ServiceManager,
                      ServiceName,
                      NativeMethods.SERVICE_CHANGE_CONFIG);

            string?ConvertedUsername = ServiceController.ConvertServiceConfigurationToWindowsUsername(
                account,
                username);

            IntPtr PasswordPointer = password != null
                                ? Marshal.SecureStringToGlobalAllocUnicode(password)
                                : IntPtr.Zero;

            try
            {
                if (!NativeMethods.ChangeServiceConfig(
                        ServiceHandle,
                        dwServiceType: NativeMethods.SERVICE_NO_CHANGE,
                        (uint)(startMode == ServiceStartMode.AutomaticDelayedStart ? ServiceStartMode.Automatic : startMode),
                        dwErrorControl: NativeMethods.SERVICE_NO_CHANGE,
                        binaryPathAndArguments,
                        lpLoadOrderGroup: null,
                        lpdwTagId: IntPtr.Zero,
                        lpDependencies: null,
                        ConvertedUsername,
                        PasswordPointer,
                        DisplayName))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                if (PasswordPointer != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocUnicode(PasswordPointer);
                }
            }

            this.DisplayName = DisplayName;

            ServiceHelper.ChangeServiceDescription(ServiceHandle, description);

            ServiceHelper.ChangeServiceDelayedAutoStartConfiguration(ServiceHandle, startMode == ServiceStartMode.AutomaticDelayedStart);

            lock (_SyncObject)
            {
                _FullConfigurationLoaded = false;
            }
        }
Example #17
0
        private void RefreshStatus(SafeServiceHandle serviceHandle)
        {
            NativeMethods.ServiceStatusInfo Status = ServiceHelper.ReadServiceStatus(serviceHandle);

            State = Status.dwCurrentState;
        }
Example #18
0
 public static extern bool ChangeServiceConfig2(
     SafeServiceHandle hService,
     uint dwInfoLevel,
     IntPtr lpInfo);
Example #19
0
 public static extern bool DeleteService(SafeServiceHandle hService);