Ho scritto un piccolo servizio che funge da server di rete locale. Per scrivere il servizio, ho seguito uno tutorial on MSDN, come scrivere un servizio utilizzando la classe ServiceBase
.Servizio causa errore SCM "ha segnalato uno stato corrente non valido 0"
Ma quando mi registro e avvio il servizio, ricevo i messaggi di errore come mostrato di seguito. Ricevo esattamente due di questi messaggi di errore all'inizio e alla fine del servizio. (Esempio = nome del servizio).
Il servizio di esempio ha riportato uno stato corrente non valido 0.
Ecco un campione minimo del mio servizio con tutte le parti interessate. Il codice inizia con una definizione di enum e struct che è stato fornito nel tutorial MSDN:
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;
};
Dopo questo, il codice di servizio che ho scritto, ridotto alle parti interessate:
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);
}
}
Il punto di ingresso principale è semplice come questo:
static void Main(string[] args)
{
ServiceBase.Run(new Service());
}
come si può vedere, il numero di messaggi di errore corrisponde al numero di SetServiceState
chiamate. Se aggiungo altre chiamate di questo tipo, il numero di messaggi di errore aumenta di conseguenza.
Quindi presumo, l'intero problema è da qualche parte nel modo in cui chiamo l'API SetServiceStatus
, ma al momento non riesco a vedere il problema.
Riesci a individuare il problema?
In ogni caso, questo è il modo corretto di creare un servizio utilizzando C# e .NET?
Grande, grazie, questo ha risolto il problema. Di solito sono consapevole di quanto sia pessima la documentazione MSDN, ma qui ho solo dato per scontato che questa definizione di struttura dell'esempio sia corretta. Hai anche ragione, gli aggiornamenti di stato manuale non sono realmente necessari. L'avvio del mio codice ha richiesto molto tempo nella prima versione, ma ho spostato tutto in un thread, perché il risultato di alcuni di questi lunghi processi non è rilevante per l'avvio. Ottimo post di blog, solo la formattazione della lista passo-passo mi dava quasi mal di testa ;-). – Flovdis
Ottimo, ha funzionato per me. È impossibile contare quanti errori MSDN ha ... questo era uno tra i numeri infiniti ... – Fabiano
Grazie mille, Rainer - Ho usato il codice di esempio di Microsoft per creare un servizio e centrare immediatamente questo problema. Ho anche aggiunto un commento alla loro pagina qui (https://technet.microsoft.com/en-us/library/cc756305(v=ws.10).aspx) che punta alla tua soluzione qui. – Rich