private bool CheckIfExistsInWindows(string serviceName)
            {
                if (string.IsNullOrWhiteSpace(serviceName))
                {
                    return(false);
                }

                var managerHandle = Windows.OpenSCManagerW(
                    null,
                    null,
                    Windows.ServiceControlManagerAccessRight.Connect
                    );

                if (managerHandle == IntPtr.Zero)
                {
                    var errorCode = Marshal.GetLastWin32Error();
                    Log($"Can not open Windows service controller manager, error code: {errorCode}");
                    return(false);
                }

                var serviceHandle = Windows.OpenServiceW(
                    managerHandle,
                    serviceName,
                    Windows.ServiceAccessRight.QueryConfig
                    );

                if (serviceHandle == IntPtr.Zero)
                {
                    var errorCode = Marshal.GetLastWin32Error();
                    if (errorCode != (int)Windows.Error.ServiceDoesNotExist)
                    {
                        Log($"Can not open Windows service \"{serviceName}\", error code: {errorCode}");
                    }
                    return(false);
                }

                Windows.CloseServiceHandle(serviceHandle);
                return(true);
            }
            private ServiceInfo ChangeStartTypeInWindows(
                string serviceName,
                StartType startType)
            {
                if (string.IsNullOrWhiteSpace(serviceName))
                {
                    return(new ServiceInfo
                    {
                        ServiceName = serviceName,
                        ErrorCode = (int)Windows.Error.InvalidName,
                        ErrorMessage = $"Service name \"{serviceName}\" is invalid"
                    });
                }

                var managerHandle = Windows.OpenSCManagerW(
                    null,
                    null,
                    Windows.ServiceControlManagerAccessRight.Connect
                    );

                if (managerHandle == IntPtr.Zero)
                {
                    var errorCode = Marshal.GetLastWin32Error();
                    return(new ServiceInfo
                    {
                        ServiceName = serviceName,
                        ErrorCode = errorCode,
                        ErrorMessage = $"Can not open Windows service controller manager, error code: {errorCode}"
                    });
                }

                var serviceInfo = new ServiceInfo
                {
                    ServiceName = serviceName,
                    StartType   = startType
                };
                var serviceHandle = Windows.OpenServiceW(
                    managerHandle,
                    serviceName,
                    Windows.ServiceAccessRight.ChangeConfig |
                    Windows.ServiceAccessRight.QueryConfig |
                    Windows.ServiceAccessRight.QueryStatus
                    );

                if (serviceHandle == IntPtr.Zero)
                {
                    var errorCode = Marshal.GetLastWin32Error();
                    serviceInfo.ErrorCode    = errorCode;
                    serviceInfo.ErrorMessage = $"Can not open Windows service \"{serviceName}\", error code: {errorCode}";
                }
                else
                {
                    var success = Windows.ChangeServiceConfigW(
                        serviceHandle,
                        Windows.ServiceType.NoChange,
                        ConvertToWindows(startType),
                        Windows.ErrorControlType.NoChange,
                        null,
                        null,
                        IntPtr.Zero,
                        null,
                        null,
                        null,
                        null
                        );
                    if (!success)
                    {
                        var errorCode = Marshal.GetLastWin32Error();
                        serviceInfo.ErrorCode    = errorCode;
                        serviceInfo.ErrorMessage = $"Can not change Windows service \"{serviceName}\" config, error code: {errorCode}";
                    }

                    serviceInfo = UpdateCurrentStateInWindows(serviceHandle, serviceInfo);

                    Windows.CloseServiceHandle(serviceHandle);
                }

                Windows.CloseServiceHandle(managerHandle);
                return(serviceInfo);
            }
            private ServiceInfo QueryStartTypeInWindows(string serviceName)
            {
                if (string.IsNullOrWhiteSpace(serviceName))
                {
                    return(new ServiceInfo
                    {
                        ServiceName = serviceName,
                        ErrorCode = (int)Windows.Error.InvalidName,
                        ErrorMessage = $"Service name \"{serviceName}\" is invalid"
                    });
                }

                var managerHandle = Windows.OpenSCManagerW(
                    null,
                    null,
                    Windows.ServiceControlManagerAccessRight.Connect
                    );

                if (managerHandle == IntPtr.Zero)
                {
                    var errorCode = Marshal.GetLastWin32Error();
                    return(new ServiceInfo
                    {
                        ServiceName = serviceName,
                        ErrorCode = errorCode,
                        ErrorMessage = $"Can not open Windows service controller manager, error code: {errorCode}"
                    });
                }

                var serviceInfo = new ServiceInfo
                {
                    ServiceName = serviceName
                };
                var serviceHandle = Windows.OpenServiceW(
                    managerHandle,
                    serviceName,
                    Windows.ServiceAccessRight.QueryConfig | Windows.ServiceAccessRight.QueryStatus
                    );

                if (serviceHandle == IntPtr.Zero)
                {
                    var errorCode = Marshal.GetLastWin32Error();
                    serviceInfo.ErrorCode    = errorCode;
                    serviceInfo.ErrorMessage = $"Can not open Windows service \"{serviceName}\", error code: {errorCode}";
                }
                else
                {
                    const uint bytesAllocated   = 8192;
                    var        serviceConfigPtr = Marshal.AllocHGlobal((int)bytesAllocated);
                    try
                    {
                        uint bytes   = 0;
                        var  success = Windows.QueryServiceConfigW(
                            serviceHandle,
                            serviceConfigPtr,
                            bytesAllocated,
                            ref bytes
                            );
                        if (success)
                        {
                            var serviceConfig = (Windows.QueryServiceConfig)Marshal.PtrToStructure(
                                serviceConfigPtr,
                                typeof(Windows.QueryServiceConfig)
                                );
                            serviceInfo.StartType = ConvertFromWindows(serviceConfig.dwStartType);
                        }
                        else
                        {
                            var errorCode = Marshal.GetLastWin32Error();
                            serviceInfo.ErrorCode    = errorCode;
                            serviceInfo.ErrorMessage = $"Can not query Windows service \"{serviceName}\" config, error code: {errorCode}";
                        }
                    }
                    catch (Exception e)
                    {
                        Log($"Can not query Windows service \"{serviceName}\" start type: {e.Message}");
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(serviceConfigPtr);
                    }

                    serviceInfo = UpdateCurrentStateInWindows(serviceHandle, serviceInfo);

                    Windows.CloseServiceHandle(serviceHandle);
                }

                Windows.CloseServiceHandle(managerHandle);
                return(serviceInfo);
            }