2009-06-24 21 views
103

Ho un servizio Windows che installo utilizzando InstallUtil.exe. Anche se ho impostato il metodo di avvio su Automatico, il servizio non si avvia quando installato, devo aprire manualmente i servizi e fare clic su Avvia. C'è un modo per avviarlo tramite la riga di comando o tramite il codice del servizio?Avvia automaticamente un servizio Windows all'installazione

risposta

180

Nella classe Installer, aggiungere un gestore per l'evento AfterInstall. È quindi possibile chiamare ServiceController nel gestore eventi per avviare il servizio.

using System.ServiceProcess; 

public ServiceInstaller() 
{ 
    //... Installer code here 
    this.AfterInstall += new InstallEventHandler(ServiceInstaller_AfterInstall); 
} 

void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e) 
{ 
    using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName)) 
    { 
     sc.Start(); 
    } 
} 

Ora quando si esegue InstallUtil sull'installer verrà installato e quindi avviato il servizio.

+39

(commento da una modifica proposta): meglio utilizzare serviceInstaller.ServiceName, se il nome del servizio viene modificato utilizzerà il nome corretto senza doverlo modificare nel codice. –

+1

Inoltre non sarebbe male racchiudere il 'ServiceController' in un'istruzione using. – ChrisO

+0

Ho bisogno di specificare l'id del programma di installazione del servizio in OnBeforeInstall. Qualcosa come serviceInstaller = serviceInstaller1; dove serviceInstaller1 è l'id del designer. Fare questo in OnBeforeInstall ha reso il lavoro sopra perfetto per me. Non ho provato ma potresti essere in grado di farlo anche nella chiamata ServiceInstaller(). –

0

Avvio automatico significa che il servizio viene avviato automaticamente all'avvio di Windows. Come altri hanno già detto, per avviarlo dalla console è necessario utilizzare il ServiceController.

+0

Non desidero farlo. Sto cercando di farlo in una volta dalla riga di comando, o all'interno delle classi di servizio di Windows. – mickyjtwin

+0

Scusate, peccato, ho perso il punto in cui avete esplicitamente escluso la possibilità di avviarlo sul pannello di controllo. –

5

E i seguenti comandi?

net start "<service name>" 
net stop "<service name>" 
3

È possibile utilizzare la seguente riga di comando per avviare il servizio:

net start *servicename* 
2

Usa ServiceController per avviare il servizio dal codice.

Aggiornamento: E il modo più corretto per avviare il servizio dalla riga di comando è utilizzare il comando "sc" (Service Controller) anziché "rete".

+6

Perché "sc" è un modo "più corretto"? Cosa c'è di sbagliato con "net start" (e il cmdlet PSH di start-service)? – Richard

+1

Perché sc può essere chiamato da una macchina remota, quindi funziona sempre. – MacGyver

0

È possibile utilizzare il metodo GetServices della classe ServiceController per ottenere un array di tutti i servizi. Quindi, trova il tuo servizio controllando la proprietà ServiceName di ciascun servizio. Quando hai trovato il tuo servizio, chiama il metodo Start per avviarlo.

È inoltre necessario verificare la proprietà Status per vedere quale stato è già presente prima di chiamare l'avvio (potrebbe essere in esecuzione, in pausa, interrotto, ecc.).

4

opzioni programmatiche per i servizi di controllo:

  • codice nativo può utilizzati, "Starting a Service". Controllo massimo con dipendenze minime ma la maggior parte del lavoro.
  • WMI: Win32_Service ha un metodo StartService. Ciò è utile per i casi in cui è necessario essere in grado di eseguire altre elaborazioni (ad esempio per selezionare il servizio).
  • PowerShell: eseguire Start-Service tramite RunspaceInvoke o creando il proprio Runspace e utilizzando il relativo metodo CreatePipeline da eseguire. Ciò vale per i casi in cui è necessario essere in grado di eseguire altre elaborazioni (ad esempio per selezionare il servizio) con un modello di codifica molto più semplice rispetto a WMI, ma dipende dall'installazione di PSH.
  • Un'applicazione .NET può utilizzare ServiceController
23

Dopo refactoring un po ', questo è un esempio di un programma di installazione completo servizio di Windows con avvio automatico:

using System.ComponentModel; 
using System.Configuration.Install; 
using System.ServiceProcess; 

namespace Example.of.name.space 
{ 
[RunInstaller(true)] 
public partial class ServiceInstaller : Installer 
{ 
    private readonly ServiceProcessInstaller processInstaller; 
    private readonly System.ServiceProcess.ServiceInstaller serviceInstaller; 

    public ServiceInstaller() 
    { 
     InitializeComponent(); 
     processInstaller = new ServiceProcessInstaller(); 
     serviceInstaller = new System.ServiceProcess.ServiceInstaller(); 

     // Service will run under system account 
     processInstaller.Account = ServiceAccount.LocalSystem; 

     // Service will have Start Type of Manual 
     serviceInstaller.StartType = ServiceStartMode.Automatic; 

     serviceInstaller.ServiceName = "Windows Automatic Start Service"; 

     Installers.Add(serviceInstaller); 
     Installers.Add(processInstaller); 
     serviceInstaller.AfterInstall += ServiceInstaller_AfterInstall;    
    } 
    private void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e) 
    { 
     ServiceController sc = new ServiceController("Windows Automatic Start Service"); 
     sc.Start(); 
    } 
} 
} 
+1

Questo codice mi ha fornito i seguenti errori/i: Si è verificata un'eccezione durante la fase di installazione. System.InvalidOperationException: si è verificata un'eccezione nel gestore eventi OnAfterInstall di System.ServiceProcess.ServiceInstaller. L'eccezione interna System.InvalidOperationException è stata generata con il seguente messaggio di errore: Impossibile avviare service serviceName sul computer "." .. L'eccezione interna System.ComponentModel.Win32Exception è stata generata con il seguente messaggio di errore: Il programma eseguibile che questo servizio è configurato per l'esecuzione non implementa il servizio. – goamn

+1

Gli errori sono stati rilevati quando ho commentato la riga "InitializeComponent()". Credo che questa riga stia duplicando tutte le altre righe poiché i log sembrano mostrare due cose identiche che accadono insieme prima dell'errore: Installazione servizio nome servizio ... Servizio nome servizio è stato installato correttamente. Creazione del nome del servizio EventLog nel registro Applicazione ... Installazione del servizio nome servizio ... Creazione del nome del servizio EventLog nel registro Applicazione ... Si è verificata un'eccezione nel gestore eventi OnAfterInstall di System.ServiceProcess.ServiceInstaller. – goamn

+0

Hai davvero salvato la mia giornata :) Grazie per questo utile commento. Dopo aver commentato la chiamata InitializeComponent(), anche il mio servizio è iniziato perfettamente – Konstantin

0

È corrotto il vostro progettista.ReAggiungi il tuo componente Installer. Dovrebbe avere un serviceInstaller e un serviceProcessInstaller. Il servizio Installer with property Startup Method impostato su Automatic avvierà l'avvio al momento dell'installazione e dopo ogni riavvio.

1

Nonostante la risposta accettata, non ero ancora in grado di avviare il servizio-- Mi è stato invece inviato un messaggio di errore durante l'installazione che indicava che il servizio appena installato non poteva essere avviato, poiché non esisteva , nonostante l'uso di this.serviceInstaller.ServiceName piuttosto che un letterale ...

alla fine ho trovato una soluzione alternativa che fa uso della linea di comando:

private void serviceInstaller_AfterInstall(object sender, InstallEventArgs e) { 
     ProcessStartInfo startInfo = new ProcessStartInfo(); 
     startInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     startInfo.FileName = "cmd.exe"; 
     startInfo.Arguments = "/C sc start " + this.serviceInstaller.ServiceName; 

     Process process = new Process(); 
     process.StartInfo = startInfo; 
     process.Start(); 
    } 
0

Solo una nota: potrebbe essere configurare il servizio in modo diverso con il interfaccia moduli per aggiungere un programma di installazione del servizio e un programma di installazione del progetto. In tal caso, sostituire dove dice serviceInstaller.ServiceName con "name from designer" .ServiceName.

In questo caso non sono necessari i membri privati.

Grazie per l'aiuto.

Problemi correlati