2012-10-14 18 views
27

Stworzyłem usługę windows z zegarem w C# .net. działa dobrze podczas debugowania/budowania projektu w visual studio, ale nie działa po instalacji.Usługa Windows z zegarem

Jaki może być tego powód?

Kod:

public partial class Service1 : ServiceBase 
{ 
     FileStream fs; 
     StreamWriter m_streamWriter; 
     Timer tm = new Timer(); 

     public Service1() 
     { 
      InitializeComponent(); 

      this.ServiceName = "timerservice"; 

      tm.Interval = 2000; 
      tm.Tick += new EventHandler(PerformOperations); 
      tm.Start(); 

      fs = new FileStream(@"c:\mcWindowsService.txt", FileMode.OpenOrCreate, FileAccess.Write); 

      m_streamWriter = new StreamWriter(fs); 
      m_streamWriter.BaseStream.Seek(0, SeekOrigin.End); 
     } 

     private void PerformOperations(object sener, EventArgs e) 
     { 
      //StreamWriter swr = new StreamWriter("c:\\test_from_database.txt",true); 

      try 
      { 
       OdbcConnection con = new OdbcConnection("DSN=liquor_data"); 

       OdbcDataAdapter adp = new OdbcDataAdapter("", con); 

       DataSet ds = new DataSet(); 

       string sql = "select * from item_group"; 
       adp.SelectCommand.CommandText = sql; 

       adp.Fill(ds, "item_group"); 

       foreach (DataRow dr in ds.Tables["item_group"].Rows) 
       { 
        //  swr.Write(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); 

        //Console.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); 
        m_streamWriter.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); 
       } 

       m_streamWriter.Flush(); 
      } 

      catch (Exception ex) 
      { 
       // swr.Write("Error :"+ ex.Message + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); } 
      } 
     } 
    } 
+0

robi konta mają uprawnienia do uruchamiania usługi Windows po instalacji? – urlreader

+0

yes..its admin .. –

+0

Spróbuj odkomentować połówkę, aby sprawdzić, czy nie ma jakiegoś błędu. Sprawdź także dzienniki zdarzeń systemu Windows pod kątem błędów. – MattW

Odpowiedz

50

pierwsze podejście z usług systemu Windows nie jest łatwe ..

Dawno temu pisałem usługę C#.

Taka jest logika klasy usług (przetestowane, działa bez zarzutu):

namespace MyServiceApp 
{ 
    public class MyService : ServiceBase 
    { 
     private System.Timers.Timer timer; 

     protected override void OnStart(string[] args) 
     { 
      this.timer = new System.Timers.Timer(30000D); // 30000 milliseconds = 30 seconds 
      this.timer.AutoReset = true; 
      this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed); 
      this.timer.Start(); 
     } 

     protected override void OnStop() 
     { 
      this.timer.Stop(); 
      this.timer = null; 
     } 

     private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
     { 
      MyServiceApp.ServiceWork.Main(); // my separate static method for do work 
     } 

     public MyService() 
     { 
      this.ServiceName = "MyService"; 
     } 

     // service entry point 
     static void Main() 
     { 
      System.ServiceProcess.ServiceBase.Run(new MyService()); 
     } 
    } 
} 

polecam Ci napisać pracę prawdziwy usług w oddzielnym metodą statyczną (dlaczego nie w aplikacji konsoli ... po prostu dodaj do niego odnośnik), aby uprościć debugowanie i oczyścić kod usługi.

Upewnij się, że odstęp czasu jest wystarczający, i zapisz w dzienniku TYLKO w trybie nadpisywania OnStart i OnStop.

Mam nadzieję, że to pomoże!

+0

"i zapisz w dzienniku TYLKO w nadpisaniach OnStart i OnStop." Czemu? Nie możesz napisać do pliku tekstowego przy każdym zdarzeniu, które upłynęło od czasu do czasu? Mam ten problem ... Mam swoją własną funkcję, która zapisuje do pliku tekstowego (log), ale to nie działa (działa tylko na początku i końcu), czy możesz mi pomóc zrozumieć, na czym polega problem? –

+0

Tak, można również pisać w metodzie timer_tick, ale dla mnie jest to niepotrzebne (główna metoda pracy musi zapisać swój log). Czy możesz pokazać mi więcej (wyjątek, itp.)? –

7

Trzeba umieścić swój główny kod na metodzie OnStart.

Ten drugi SO answer może mi pomóc.

Będziesz musiał umieścić kod, aby włączyć debugowanie w visual-studio przy zachowaniu aplikacji ważnej jako usługa Windows. Ten inny numer SO thread obejmuje kwestię debugowania usługi Windows.

EDIT:

Proszę zobaczyć również dokumentację dostępną here dla metody OnStart na MSDN, gdzie można przeczytać:

Nie używać konstruktora do wykonywania przetwarzania, które powinny być w OnStart. Użyj opcji OnStart, aby obsłużyć wszystkie inicjalizacje usługi. Konstruktor jest wywoływany, gdy uruchamiany jest plik wykonywalny aplikacji, a nie gdy usługa działa. Plik wykonywalny działa przed OnStart. Kiedy kontynuujesz, np. , konstruktor nie jest ponownie wywoływany, ponieważ SCM już przechowuje obiekt w pamięci. Jeśli OnStop zwalnia zasoby przydzielone w konstruktorze, zamiast w onStart, że potrzebne środki nie byłyby tworzone ponownie po raz drugi usługa jest nazywa.

0

Oto przykład roboczych, w których wykonanie usługi jest uruchamiany w OnTimedEvent na zegar, który jest zaimplementowany jako delegat w klasie ServiceBase i logiki timera jest zawarta w metodzie zwanej SetupProcessingTimer():

public partial class MyServiceProject: ServiceBase 
{ 

private Timer _timer; 

public MyServiceProject() 
{ 
    InitializeComponent(); 
} 

private void SetupProcessingTimer() 
{ 
    _timer = new Timer(); 
    _timer.AutoReset = true; 
    double interval = Settings.Default.Interval; 
    _timer.Interval = interval * 60000; 
    _timer.Enabled = true; 
    _timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
} 

private void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    // begin your service work 
    MakeSomething(); 
} 

protected override void OnStart(string[] args) 
{ 
    SetupProcessingTimer(); 
} 

... 
} 

przedziału jest zdefiniowane w app.config w minutach:

<userSettings> 
    <MyProject.Properties.Settings> 
     <setting name="Interval" serializeAs="String"> 
      <value>1</value> 
     </setting> 
    </MyProject.Properties.Settings> 
</userSettings> 
Powiązane problemy