Come avviare un servizio Windows .NET subito dopo l’installazione?

Oltre a service.StartType = ServiceStartMode.Automatic il mio servizio non si avvia dopo l’installazione

Soluzione

Inserito questo codice sul mio ProjectInstaller

protected override void OnAfterInstall(System.Collections.IDictionary savedState) { base.OnAfterInstall(savedState); using (var serviceController = new ServiceController(this.serviceInstaller1.ServiceName, Environment.MachineName)) serviceController.Start(); } 

Grazie a ScottTx e Francis B.

È ansible eseguire tutto questo all’interno del servizio eseguibile in risposta agli eventi generati dal processo InstallUtil. Sostituire l’evento OnAfterInstall per utilizzare una class ServiceController per avviare il servizio.

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

Ho pubblicato una procedura dettagliata per la creazione di un servizio Windows in C # qui . Sembra che tu sia almeno fino a questo punto e ora ti stai chiedendo come avviare il servizio una volta installato. L’impostazione della proprietà StartType su Automatic farà sì che il servizio si avvii automaticamente dopo il riavvio del sistema, ma non (come hai scoperto) avvierà automaticamente il servizio dopo l’installazione.

Non ricordo dove l’ho trovato in origine (forse Marc Gravell?), Ma ho trovato una soluzione online che ti permette di installare e avviare il tuo servizio eseguendo effettivamente il tuo servizio stesso. Ecco il passo-passo:

  1. Struttura la funzione Main() del tuo servizio in questo modo:

     static void Main(string[] args) { if (args.Length == 0) { // Run your service normally. ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()}; ServiceBase.Run(ServicesToRun); } else if (args.Length == 1) { switch (args[0]) { case "-install": InstallService(); StartService(); break; case "-uninstall": StopService(); UninstallService(); break; default: throw new NotImplementedException(); } } } 
  2. Ecco il codice di supporto:

     using System.Collections; using System.Configuration.Install; using System.ServiceProcess; private static bool IsInstalled() { using (ServiceController controller = new ServiceController("YourServiceName")) { try { ServiceControllerStatus status = controller.Status; } catch { return false; } return true; } } private static bool IsRunning() { using (ServiceController controller = new ServiceController("YourServiceName")) { if (!IsInstalled()) return false; return (controller.Status == ServiceControllerStatus.Running); } } private static AssemblyInstaller GetInstaller() { AssemblyInstaller installer = new AssemblyInstaller( typeof(YourServiceType).Assembly, null); installer.UseNewContext = true; return installer; } 
  3. Continuando con il codice di supporto …

     private static void InstallService() { if (IsInstalled()) return; try { using (AssemblyInstaller installer = GetInstaller()) { IDictionary state = new Hashtable(); try { installer.Install(state); installer.Commit(state); } catch { try { installer.Rollback(state); } catch { } throw; } } } catch { throw; } } private static void UninstallService() { if ( !IsInstalled() ) return; try { using ( AssemblyInstaller installer = GetInstaller() ) { IDictionary state = new Hashtable(); try { installer.Uninstall( state ); } catch { throw; } } } catch { throw; } } private static void StartService() { if ( !IsInstalled() ) return; using (ServiceController controller = new ServiceController("YourServiceName")) { try { if ( controller.Status != ServiceControllerStatus.Running ) { controller.Start(); controller.WaitForStatus( ServiceControllerStatus.Running, TimeSpan.FromSeconds( 10 ) ); } } catch { throw; } } } private static void StopService() { if ( !IsInstalled() ) return; using ( ServiceController controller = new ServiceController("YourServiceName")) { try { if ( controller.Status != ServiceControllerStatus.Stopped ) { controller.Stop(); controller.WaitForStatus( ServiceControllerStatus.Stopped, TimeSpan.FromSeconds( 10 ) ); } } catch { throw; } } } 
  4. A questo punto, dopo aver installato il servizio sul computer di destinazione, è sufficiente eseguire il servizio dalla riga di comando (come qualsiasi normale applicazione) con l’argomento della riga di comando -install per installare e avviare il servizio.

Penso di aver coperto tutto, ma se trovi che questo non funziona, faccelo sapere, così posso aggiornare la risposta.

Visual Studio

Se si sta creando un progetto di installazione con VS, è ansible creare un’azione personalizzata che ha chiamato un metodo .NET per avviare il servizio. Tuttavia, non è consigliabile utilizzare l’azione personalizzata gestita in un MSI. Vedi questa pagina .

 ServiceController controller = new ServiceController(); controller.MachineName = "";//The machine where the service is installed; controller.ServiceName = "";//The name of your service installed in Windows Services; controller.Start(); 

InstallShield o Wise

Se si utilizza InstallShield o Wise, queste applicazioni forniscono l’opzione per avviare il servizio. Ad esempio con Wise, devi aggiungere un’azione di controllo del servizio. In questa azione, si specifica se si desidera avviare o interrompere il servizio.

Wix

Usando Wix devi aggiungere il seguente codice xml sotto il componente del tuo servizio. Per ulteriori informazioni a riguardo, è ansible controllare questa pagina .

   ///Add any dependancy to your service  

È necessario aggiungere un’azione personalizzata alla fine della sequenza “ExecuteImmediate” nell’MSI, utilizzando come origine il nome componente dell’EXE o un batch (sc start). Non penso che questo possa essere fatto con Visual Studio, potrebbe essere necessario utilizzare un vero strumento di authoring MSI per questo.

Per avviarlo subito dopo l’installazione, creo un file batch con installutil seguito da sc start

Non è l’ideale, ma funziona ….

Utilizzare la class .NET ServiceController per avviarlo o emettere il comando commandline per avviarlo — “net start servicename”. In entrambi i casi funziona.

Per aggiungere alla risposta di ScottTx, ecco il codice effettivo per avviare il servizio se lo stai facendo in modo Microsoft (ad esempio utilizzando un progetto di installazione ecc …)

(scusa il codice VB.net, ma questo è quello con cui sono bloccato)

 Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall Dim sc As New ServiceController() sc.ServiceName = ServiceInstaller1.ServiceName If sc.Status = ServiceControllerStatus.Stopped Then Try ' Start the service, and wait until its status is "Running". sc.Start() sc.WaitForStatus(ServiceControllerStatus.Running) ' TODO: log status of service here: sc.Status Catch ex As Exception ' TODO: log an error here: "Could not start service: ex.Message" Throw End Try End If End Sub 

Per creare il gestore di eventi sopra, andare al designer ProjectInstaller dove si trovano i 2 controller. Fare clic sul controllo ServiceInstaller1. Vai alla finestra delle proprietà sotto eventi e lì troverai l’evento AfterInstall.

Nota: non inserire il codice precedente nell’evento AfterInstall per ServiceProcessInstaller1. Non funzionerà, provenendo dall’esperienza. 🙂

La soluzione più semplice si trova qui install-windows-service-without-installutil-exe di @ Hoàng Long

 @echo OFF echo Stopping old service version... net stop "[YOUR SERVICE NAME]" echo Uninstalling old service version... sc delete "[YOUR SERVICE NAME]" echo Installing service... rem DO NOT remove the space after "binpath="! sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto echo Starting server complete pause