Service causes SCM error "reported invalid current state 0"

I wrote a small service that acts like a local network server. To write a service, I completed a tutorial on MSDN how to write a service using the ServiceBase class.

But when I register and start the service, I get error messages as shown below. I get exactly two of these error messages at the beginning and when the service stops. (Example = service name).

The Example service reported an invalid current state of 0.

Here is a minimal sample of my service with all the relevant parts. The code begins by defining the enumeration and structure that was provided in the MSDN tutorial:

 public enum ServiceState { SERVICE_STOPPED = 0x00000001, SERVICE_START_PENDING = 0x00000002, SERVICE_STOP_PENDING = 0x00000003, SERVICE_RUNNING = 0x00000004, SERVICE_CONTINUE_PENDING = 0x00000005, SERVICE_PAUSE_PENDING = 0x00000006, SERVICE_PAUSED = 0x00000007, } [StructLayout(LayoutKind.Sequential)] public struct ServiceStatus { public long dwServiceType; public ServiceState dwCurrentState; public long dwControlsAccepted; public long dwWin32ExitCode; public long dwServiceSpecificExitCode; public long dwCheckPoint; public long dwWaitHint; }; 

After that, the service code that I wrote comes down to the relevant parts:

 namespace example { public partial class Service : ServiceBase { public Service() : base() { this.ServiceName = "ExampleService"; this.AutoLog = false; this.CanStop = true; this.CanShutdown = false; this.CanPauseAndContinue = false; this.CanHandlePowerEvent = false; this.CanHandleSessionChangeEvent = false; } protected override void OnStart(string[] args) { try { SetServiceState(ServiceState.SERVICE_START_PENDING, 100000); // ... initialise and start... SetServiceState(ServiceState.SERVICE_RUNNING); } catch (System.Exception ex) { SetServiceState(ServiceState.SERVICE_STOPPED); } } protected override void OnStop() { SetServiceState(ServiceState.SERVICE_STOP_PENDING, 100000); // ... stop service ... SetServiceState(ServiceState.SERVICE_STOPPED); } private void SetServiceState(ServiceState state, int waitHint = 0) { ServiceStatus serviceStatus = new ServiceStatus(); serviceStatus.dwCurrentState = state; serviceStatus.dwWaitHint = waitHint; SetServiceStatus(this.ServiceHandle, ref serviceStatus); } [DllImport("advapi32.dll", SetLastError=true)] private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus); } } 

The main entry point is simple:

 static void Main(string[] args) { ServiceBase.Run(new Service()); } 

As you can see, the number of error messages corresponds to the number of calls to SetServiceState . If I add additional calls, the number of error messages increases accordingly.

So, I assume that the whole problem is what I call the SetServiceStatus API, but currently I don't see the problem.

Can you spot the problem?

Anyway, is this the right way to create a service using C # and .NET?

+6
source share
1 answer

Firstly:

Usually there is no need to call the SetServiceState method. This may be necessary if your service really takes a long time to initialize (where you can tell SCM that you are still alive with SERVICE_START_PENDING and take a few more seconds). Usually you start the stream on OnStart and return as soon as possible.

I have written many services in C # in recent years and have never needed it.

But - I found an error in the MSDN code example (I tested your code myself).

In ServiceStatus struct, replace long with int or (best block). If you are using uint, you must also change this in the SetServiceState method.

Also see Should DWORD match int or uint? .

If you are interested in a small introduction on how you can start with a Windows service in C # with additional customization, you can check out my blog post:

http://www.rsprog.de/samplewindowsservice/

[Update 2018-01-20]

I created a new article about this that uses the self-installation method, which has the advantage (at least for me) that it does not require an extension of the Visual Studio installation project

http://www.rsprog.de/windowsserviceselfinstall/

+14
source

Source: https://habr.com/ru/post/987407/


All Articles