2010-11-10 14 views
35

Ho letto questa domanda Inno Setup for Windows service?. Ho lo stesso problema, ma non capisco la risposta di lubos hasko. Come posso farlo esattamente? Qualcuno può pubblicarmi una guida completa?Servizio Windows di installazione automatica in .NET C#

Quando eseguo il codice di seguito, qualcosa è installato, ma in elenco di servizio, non riuscivo a trovarlo. Ho questo, ma questo non funziona:

using System; 
using System.Collections.Generic; 
using System.Configuration.Install; 
using System.Linq; 
using System.Reflection; 
using System.ServiceProcess; 
using System.Text; 
using System.IO; 

namespace ConsoleApplication1 
{ 

public class Service1 : ServiceBase 
{ 

    public Service1() 
    { 
     File.AppendAllText("sss.txt", "ccccc"); 
    } 

    protected override void OnStart(string[] args) 
    { 
     File.AppendAllText("sss.txt", "asdfasdf"); 
    } 

    protected override void OnStop() 
    { 
     File.AppendAllText("sss.txt", "bbbbb"); 
    } 


    static void Main(string[] args) 
    { 
     if (System.Environment.UserInteractive) 
     { 
      string parameter = string.Concat(args); 
      switch (parameter) 
      { 
       case "--install": 
        ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); 
        break; 
       case "--uninstall": 
        ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); 
        break; 
      } 
     } 
     else 
     { 
      ServiceBase.Run(new Service1()); 
     } 


     Console.ReadKey(); 
    } 
} 
} 

I dont understad questa operazione:

if (System.Environment.UserInteractive) ... 

risposta

72

Questa è la mia soluzione completa e funziona. È fondamentalmente la stessa risposta della domanda this.

using System; 
using System.Configuration.Install; 
using System.Reflection; 
using System.ServiceProcess; 
using System.IO; 

namespace ConsoleApplication1 
{ 
    class Program : ServiceBase 
    { 
     static void Main(string[] args) 
     { 

      AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException; 


      if (System.Environment.UserInteractive) 
      { 
       string parameter = string.Concat(args); 
       switch (parameter) 
       { 
        case "--install": 
         ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); 
         break; 
        case "--uninstall": 
         ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); 
         break; 
       } 
      } 
      else 
      { 
       ServiceBase.Run(new Program()); 
      } 



     } 

     private static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) 
     { 
      File.AppendAllText(@"C:\Temp\error.txt", ((Exception)e.ExceptionObject).Message + ((Exception)e.ExceptionObject).InnerException.Message); 
     } 

     public Program() 
     { 
      this.ServiceName = "My Service"; 
      File.AppendAllText(@"C:\Temp\sss.txt", "aaa"); 

     } 

     protected override void OnStart(string[] args) 
     { 
      base.OnStart(args); 

      File.AppendAllText(@"C:\Temp\sss.txt", "bbb"); 
     } 

     protected override void OnStop() 
     { 
      base.OnStop(); 

      File.AppendAllText(@"C:\Temp\sss.txt", "ccc"); 
     } 
    } 
} 

e nel medesimo progetto creare questa classe:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Configuration.Install; 
using System.Linq; 
using System.ServiceProcess; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    [RunInstaller(true)] 
    public class MyWindowsServiceInstaller : Installer 
    { 
     public MyWindowsServiceInstaller() 
     { 
      var processInstaller = new ServiceProcessInstaller(); 
      var serviceInstaller = new ServiceInstaller(); 

      //set the privileges 
      processInstaller.Account = ServiceAccount.LocalSystem; 

      serviceInstaller.DisplayName = "My Service"; 
      serviceInstaller.StartType = ServiceStartMode.Automatic; 

      //must be the same as what was set in Program's constructor 
      serviceInstaller.ServiceName = "My Service"; 
      this.Installers.Add(processInstaller); 
      this.Installers.Add(serviceInstaller); 
     } 
    } 
} 

Esegui questo programma con i parametri --install/- disinstallazione come Amministratore su Windows 7. Controllare il log degli errori in temperatura. Controllare il registro di lavoro sullo stesso percorso.

0

System.Environment.UserInteractive proprietà che si dice che se un processo di Windows o di un servizio come IIS che viene eseguito senza un utente interfaccia.

Se questa proprietà è false, non visualizzare finestre di dialogo modali o finestre di messaggio perché non c'è un'interfaccia utente grafica con cui l'utente possa interagire. Source

check this articolo pure.

+0

Grazie, quell'articolo mi ha davvero aiutato. Ma nell'articolo, l'autore ha usato installutil. Non voglio usare installutil. C'è qualche opzione? La risposta è in questo articolo http://stackoverflow.com/questions/1449994/inno-setup-for-windows-service/1450051#1450051 ma non so come usarlo. – Simon

+0

Perché non vuoi installare un servizio con installutil? Se è a causa di autorizzazioni, non sarà possibile installare un servizio senza diritti di amministratore. Non c'è da fare per questo. – jlafay

+0

In realtà, sto ancora utilizzando installutil, ma attraverso ManagedInstallerClass.InstallHelper. Questo è il punto. Quando distribuisco il mio programma, non è necessario distribuire anche installutil.exe. L'installazione del WS viene effettuata durante l'installazione dell'applicazione con Inno Setup, e questa viene effettuata con diritti di amministratore, quindi nessun problema ... – Simon

1

Prima di tutto nella proprietà ServiceName del costruttore Service1.

Estratto dal MSDN:

Il minimo è necessario implementare nel costruttore per una classe ereditata da ServiceBase è quello di impostare il ServiceName sul componente. Nessun'altra elaborazione è specificatamente richiesta nel costruttore. Dovresti gestire la maggior parte dell'inizializzazione in OnStart piuttosto che nel costruttore.

In secondo luogo è necessario passare argomenti al servizio durante l'esecuzione dalla riga di comando. --install per l'installazione, --uninstall per la disinstallazione: guarda l'istruzione del tuo switch su argomenti di input.

+0

Sì, i parametri passati e il costrutto corretto. Ancora senza fortuna. – Simon

+0

Doh! Vedi la risposta di Simon, quella parte dell'installatore è mancante. – Mihailo

+0

Btw, hai un'opzione, quando aggiungi un nuovo elemento a un progetto, per selezionare il servizio di Windows (fai clic con il tasto destro del mouse sul progetto, nel menu a comparsa scegli Aggiungi -> Nuovo elemento ... e trova lì il servizio di Windows). Dopo averlo aggiunto in questo modo è possibile impostare correttamente le proprietà del servizio e aggiungere programmi di installazione ecc. – Mihailo

Problemi correlati