I wrote a small service, which acts as a local network server. To write the service, I followed 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 start and at the service stop. (Example = name of service).
The Example service has reported an invalid current state 0.
Here a minimal sample of my service with all relevant parts. The code starts with an enum and struct definition which 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 this, the service code I wrote, reduced 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 as this:
static void Main(string[] args)
{
ServiceBase.Run(new Service());
}
As you can see, the number of error messages matches the number of SetServiceState
calls. If I add additional such calls, the number of error messages increases accordingly.
So I assume, the whole problem is somewhere in the way I call the SetServiceStatus
API, but I currently can't see the problem.
Can you spot the Problem?
Anyway is this the correct way to build a Service using C# and .NET?