2009-05-03 21 views
24

Sto cercando di creare diversi servizi Windows per fare cose diverse. Per esempio, ho bisogno di servizi di Windows che sarà:Più servizi Windows in un exe

  1. Invia un report giornaliero via e-mail
  2. periodicamente la pulizia di alcune informazioni archiviate ogni 30 minuti
  3. ecc

I compiti ho bisogno le finestre i servizi da fare sono distinti quindi non mi piace l'idea di averli tutti in un unico servizio.

Quello che ho finora è un progetto in Visual Studio 2008. Ho creato un servizio di Windows, ho impostato un timer sull'evento OnStart (solo scrive in un file di testo ogni 5 secondi per scopi di test). Ho quindi aggiunto un programma di installazione al progetto e quando eseguo InstallUtil.exe, tutto funziona correttamente.

Il problema si presenta quando aggiungo un secondo servizio Windows allo stesso progetto. Ho impostato nuovamente il codice OnStart, con le stesse informazioni di registrazione (leggermente diverse in modo da poter dire quale servizio sta scrivendo nel registro). Con il secondo servizio di Windows, ho cambiato l'evento principale in Program.cs da:

static void Main(string[] args) 
    { 
     ServiceBase[] ServicesToRun = new ServiceBase[] 
     { 
      new Service1() 
     }; 

     ServiceBase.Run(ServicesToRun); 
    } 

a:

static void Main(string[] args) 
    { 
     ServiceBase[] ServicesToRun = new ServiceBase[] 
     { 
      new Service1(), 
      new Service2() 
     }; 

     ServiceBase.Run(ServicesToRun); 
    } 

A questo punto, non ci sono errori di compilazione, ma il servizio non fa mai Service2 qualsiasi cosa ... l'attività di registrazione non viene mai attivata.

Ho ridotto il limite al fatto che al secondo servizio non è associato "Installer". Ho quindi provato ad aggiungere un programma di installazione come ho fatto con il primo servizio (ad esempio, fare clic con il tasto destro del mouse sul progettista del servizio e fare clic su "Aggiungi programma di installazione"). Ora, quando vado al file ProjectInstaller.cs, c'è un altro serviceInstaller lì (serviceInstaller2).

Ora, quando ho costruire il progetto e cercare di installare i servizi, e vado alla finestra del pannello di controllo "Servizi", e cerco di iniziare Service1, ottengo il seguente messaggio di errore:

di Windows Impossibile avviare il servizio Service1 sul computer locale.

Errore 1083: il programma eseguibile per cui questo servizio è configurato per l'esecuzione non implementa il servizio.

Viene visualizzato lo stesso messaggio di errore se si tenta di avviare anche Service2 (con l'eccezione che il messaggio di errore identifica Service2, ovviamente).

C'è qualcosa che mi manca per ottenere due servizi in esecuzione da un exe?

+0

C'è un motivo particolare diverso da "voglio" che si bisogno di avere i servizi in un singolo eseguibile? Normalmente, la modularità sarebbe preferibile, ma potresti avere circostanze attenuanti che richiedono diversamente. – bsneeze

+0

L'unica vera ragione è la facilità di installazione e distribuzione. Tutti i "servizi" sono abbastanza veloci, una parte delle funzionalità, quindi preferirei non dover installare il numero x di servizi Windows per piccoli pezzi di codice. –

+0

@pyrochild - Sono sicuro che ci sono numerosi motivi per montare più servizi all'interno di un singolo assemblaggio. Dove lavoro ora usiamo bestie di quel design su una base per cliente - rende il test del software che interagisce con quei servizi in un attimo. – Hardryv

risposta

1

In realtà sto costruendo qualcosa di molto simile a quello a cui stai pensando. Quello che ho deciso di fare (finora) è avere tutti i miei "servizi" (anche se non sono servizi, l'unico "controller" è) implementare una particolare interfaccia (con operazioni init() ed execute() pure come una enumerazione di FREQUENZA).

Il controller è il servizio di Windows e si legge l'elenco dei programmi/DLL da un file di impostazioni XML in fase di esecuzione e li carica in un elenco e chiede il loro metodo execute() (se del caso) su qualsiasi frequenza hanno definito.

Nel mio caso, ogni programma contiene anche un controllo utente che viene caricato in una scheda del controller che consente all'utente di controllarlo/modificarlo. Pubblicherò il codice se sei interessato.

Non so se fosse chiaro. In realtà ho avuto l'idea da un altro utente SO che ha implementato qualcosa di simile ma non riesco a trovare quel post ora.

2

Ho avuto un problema simile oggi e sono riuscito a risolverlo.

In primo luogo, mi sono assicurato che ciascuno dei servizi avesse una proprietà ServiceName significativa e unica. Il generatore diede ad entrambi i servizi lo stesso nome che non avrebbe aiutato.

Ho quindi rimosso e rigenerato la classe ProjectInstaller e aggiunto i programmi di installazione per ciascuna classe. Mi sono assicurato che fossero entrambi istanziati nel metodo Main statico.

Ora posso installare i due servizi con la dll, ma sfortunatamente quando avvio uno dei servizi sembra che esegua le funzioni sia di se stesso che dell'altro servizio. Cioè, entrambi i servizi sono in esecuzione (anche se solo uno dei servizi appare come "avviato" in Gestione computer). Sto ancora cercando di capirlo ...

0

Ho avuto lo stesso problema oggi e sono riuscito a risolverlo. Nel mio caso ho solo dovuto aprire i file * .designer.cs dei miei servizi e accertarmi che il nome del servizio sia impostato correttamente. Ancora più importante, lo stesso nome dovrebbe essere usato in * Installer.Designer.cs e se hai il codice in * Installer.cs.

Penso che questo errore si verifichi solo a causa della mancata corrispondenza del nome.

Spero che questo helpds

4

Immagino che voi ragazzi hanno già risolto questo, ma nel caso in cui qualche altro ne ha bisogno, vi posterò una risposta a questo problema che mi sono volute diverse ore di oggi. Le soluzioni non devono aggiungere un altro programma di installazione del progetto, ma un programma di installazione del servizio, che è un componente del programma di installazione del progetto. Il programma di installazione del servizio appena aggiunto deve avere un secondo nome di servizio configurato.

+0

Ho dovuto usare il dettaglio qui per dirmi come fare questo: https : //msdn.microsoft.com/en-us/library/zt39148a (v = vs.110) .aspx Per i pigri: "Apri il menu di scelta rapida per la finestra di progettazione (se stai utilizzando un dispositivo di puntamento, a destra- fare clic all'interno della finestra), quindi selezionare Aggiungi programma di installazione. " – wilsjd

+0

Non sono riuscito a capire cosa intendevi con i punti 6 e 7. –

14

Ho capito come avere un eseguibile ma due servizi. Ogni servizio viene installato nel gestore servizi con il proprio nome e la capacità di avviarsi/arrestarsi. Penso che questo sia quello che vuoi, giusto? Ecco cosa ho fatto:

  1. Creato un progetto di servizio.
  2. Aggiunto un secondo servizio per lo stesso progetto (con un nome di servizio univoco).
  3. Aggiunto un programma di installazione per entrambi i servizi (ServiceA e ServiceB).
  4. Nel file ProjectInstaller.Designer.vb ho modificato la riga Me.Installers.AddRange per mostrare entrambi i programmi di installazione del servizio. (Me.ServiceInstaller1, Me.ServiceInstaller2)
  5. Nel punto di ingresso Principale del servizio principale (ServiceA nel mio caso), ho impostato la variabile ServicesToRun su un array di ServiceBase che contiene tutti i servizi che voglio che esegua (ServiceA e servizio B). Questo è un passo importante in quanto il gestore dei servizi imposta una proprietà in base al numero di argomenti qui - o per consentire più istanze dello stesso exe o solo una singola istanza.
  6. Aggiungere un progetto di installazione e utilizzare l'output di Servizi.
  7. Aggiungere un'azione personalizzata utilizzando l'output da Servizi.

È possibile trovare il codice demo qui:
http://code.google.com/p/multi-service-install/

Enjoy!

0

L'installazione di 2 servizi distinti e non correlati in un file eseguibile ha un odore strano per me. Mentre è possibile farlo funzionare, non lo rende giusto.

Da quello che sembra, è necessario eseguire alcune attività diverse a vari intervalli e le attività possono essere o non essere correlate. Hai esaminato Quartz.NET? Sembra una buona misura per le tue esigenze.

http://quartznet.sourceforge.net/features.html

1

ho usato sc.exe per raggiungere questo facilmente. http://support.microsoft.com/kb/251192

Per esempio: sc create "My Display Service Name" binpath= "c:\app\mysvc.exe --service"

Nota: tutti uguali dovrebbe avere spazio prima il suo valore, come si può vedere di 'binpath'

Problemi correlati