2012-10-14 19 views
27

私はタイマー付きのWindowsサービスをc#.netで作成しました。ビジュアルスタジオでプロジェクトをデバッグ/ビルドしている間は正常に動作しますが、インストール後には動作しません。タイマー付きWindowsサービス

この理由は何でしょうか。

コード:

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

アカウントは、インストール後にWindowsサービスを実行する権限を持っていますか? – urlreader

+0

yes..its admin .. –

+0

キャッチのコメントを外して、何らかのエラーが発生していないかどうかを確認してください。また、Windowsイベントログにエラーがないかチェックしてください。 – MattW

答えて

50

最初のアプローチは容易ではない..です

長い時間前に、私はC#のサービスを書きました。

これは(テストし、正常に動作します)サービスクラスのロジックです:

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()); 
     } 
    } 
} 

私はあなたがコンソールアプリケーションで別の静的メソッド(なぜ、中にあなたの本当のサービス作業を書くお勧めします...デバッグを単純化し、サービスコードをクリーンアップするために、それへの参照を追加するだけです)。

間隔が十分であることを確認し、OnStartおよびOnStopオーバーライドにのみログを書き込みます。

希望すると便利です。ここで

+0

"を作成し、OnStartとOnStopの上書きでのみログに書き込みます。どうして?タイマー経過イベントごとにテキストファイルに書き込めませんか?私はその問題を抱えています...私はテキストファイル(ログ)に書き込む独自の関数を持っていますが、それは動作していません(ちょうど開始と停止で動作します)。 –

+0

はい、timer_tickメソッドに書き込むこともできますが、私にとっては不要です(メインワークメソッドはログを書き込む必要があります)。あなたはもっと私を見せてもらえますか(例外など)? –

7

あなたはOnStart方法であなたのメインのコードを配置する必要があります。

この他SO answer私の助けかもしれません。

ビジュアルスタジオ内でデバッグを有効にするために、アプリケーションをWindowsサービスとして有効にしておくために、いくつかのコードを記述する必要があります。この他のSO threadは、Windowsサービスのデバッグの問題をカバーしています。

EDIT

1は、これを読むことができますMSDNでOnStart方法についてhere可能なドキュメントも参照してください:

はであるべき処理を実行するために、コンストラクタを使用しないでください OnStartOnStartを使用して、サービスのすべての初期化を処理します。 コンストラクタは、アプリケーションの実行可能ファイルが実行されるときに呼び出され、 サービスが実行されているときは呼び出されません。実行可能ファイルは、OnStartより前に実行されます。たとえば、 を続行すると、 SCMが既にオブジェクトをメモリに保持しているため、コンストラクターが再度呼び出されません。コンストラクタではなくのOnStartに割り当てられたOnStopリソースを解放し 場合は、必要に応じ リソースが再びサービスが と呼ばれる第二の時間を作成することはないだろう。 Windowsサービスと

0

は、サービスの実行がServiceBaseクラスにデリゲートとして実装されると、タイマ・ロジックはSetupProcessingTimer(と呼ばれる方法でカプセル化されたタイマ)のOnTimedEventに開始される作業例です:

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(); 
} 

... 
} 

間隔は分単位でApp.configファイルで定義されています

<userSettings> 
    <MyProject.Properties.Settings> 
     <setting name="Interval" serializeAs="String"> 
      <value>1</value> 
     </setting> 
    </MyProject.Properties.Settings> 
</userSettings> 
関連する問題