eventLog
とを使用して Windows サービスを実装しました。FileSystemWatcher
これは、特定のディレクトリの変更を検索し、メッセージを に書き込みますMyLog
。
奇妙なこと1:
installUtil.exeを介してインストールし(VS2012にはインストーラーテンプレートがないため)、「サービス」に移動してサービスを開始すると、次のような状況が発生します。
ローカル コンピューターの [サービス名] サービスが開始され、その後停止されました。一部のサービスは、別のサービスまたはプログラムによって使用されていない場合、自動的に停止します。
私はすでにこの質問を見ました。この投稿からの2つの回答がなぜそうなのか:
OnStart()
1)メソッドで開始するスレッドがありません。
私はデザイナーを使用し、[プロパティ] ウィンドウでほとんどのプロパティを設定します。手動でスレッドを開始したことはありませんが、場合によってはすべてが機能していたので、そうではないと思います。
2) メソッドで例外が発生しOnStart()
ます。コードを変更していないため、そうではないと思います。同じサービスをアンインストール、ビルド、および再インストールするだけで、実行される場合と実行されない場合があります。
このことで 2 時間ほど立ち往生したとき、「FilesMonitoringServices」のSource
プロパティが長すぎることに気付きました。eventLog
「MonitorSource」に変更すると、すべてが機能し始めました。何回か再インストールしたところ、上記と同じ警告が表示されました。Source
プロパティを再度変更したところ、サービスが実行されるようになりました。
これが最初の奇妙なことです。
奇妙なこと 2:もっと悪い。ログOnStart()
とOnStop()
メソッドのみを実行しても、fileSystemWatcher イベント ハンドラーが実行されないことを意味します。今日、このサービス mabby を 100 回再インストールしましたが、3 回は機能していましたが、もう一度再インストールすると停止しました。そして、再インストールの間にコードをまったく変更していません。
継承する私のクラス(MonitoringService)のメソッドとコンストラクターは次のServiceBase
とおりです。
public MonitoringService()
{
InitializeComponent();
if (!EventLog.SourceExists(eventLog.Source))
{
EventLog.CreateEventSource(eventLog.Source, eventLog.Log);
}
// haven't changed it between the reinstallations
fileWatcher.Path = @"path";
}
protected override void OnStart(string[] args)
{
fileWatcher.EnableRaisingEvents = true;
eventLog.WriteEntry("start", EventLogEntryType.Information);
base.OnStart(args);
}
protected override void OnStop()
{
fileWatcher.EnableRaisingEvents = false;
fileWatcher.Dispose();
eventLog.WriteEntry("stop", EventLogEntryType.Information);
base.OnStop();
}
ファイル システム ウォッチャー イベント ハンドラ:
private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
{
using (var conn = new SqlConnection(GetConnectionString()))
{
conn.Open();
var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value);
const string cmd = "UPDATE Products SET ImageModifiedDate=@date WHERE ProductId=@productId";
using (var command = new SqlCommand(cmd, conn))
{
command.Parameters.AddWithValue("@productId", productId);
command.Parameters.AddWithValue("@date", DateTime.Now);
command.ExecuteNonQuery();
}
}
eventLog.WriteEntry(string.Format("{0} has been changed: {1}", e.Name, DateTime.Now), EventLogEntryType.Information);
}
質問:この動作は私のコードではなく、オペレーティング システムの設定が原因のようです。そうでしょうか?
****編集:より具体的なものを発見しました:**
1) メッセージが表示された場合 (サービスを開始したい場合):
The [service name] service on local computer started and then stopped. ....
Source
のプロパティを変更し、再構築して再インストールする必要がありeventLog
ます。このメッセージは表示されません。次回はマビー。
2) 次のフォルダ階層があります: images/prod-images
. images
ディレクトリとprod-images
ディレクトリの両方に画像ファイルが含まれています。サービスの実行中にフォルダーからイメージを変更すると、必要に応じprod-images
てメッセージがログに書き込まれ、データベースが更新されます。しかし、このイベントの後、サービスは停止します! (私はこれを3回チェックしました)。そして、再起動してこれを数回繰り返すと、データベースが更新され、ログが書き込まれ、3 番目の時間に取得されます
The [service name] service on local computer started and then stopped. ....
しかし、これは最良の部分ではありません) ディレクトリにある画像を変更するimages
と、何度でも変更できますが、サービスは停止しません。(からの画像のみimages/prod-images
がデータベースのエントリにバインドされます)。
それで、この機能はどういうわけかデータベースへのアクセスを指しているでしょうか?
編集 2:ビジュアル スタジオではDEBUG -> Attach to Process
、サービスのデバッグに使用します。ブレークポイントを設定して画像を変更します。初めてイベント ハンドラーが問題なく実行されます。データベースが更新され、ログ メッセージが書き込まれます。しかし、F11 (ステップ イン) を押し続けると、このイベント ハンドラーが 2 回目に実行されます。ラインで
var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value);
「処理されていません」とFormatException
表示されます。この後、デバッグを停止すると、サービスが停止します! それだけです: 例外はイベント ハンドラーで発生します。
なぜ2回目に実行されるのか分かりますか? ありがとう!
PS私はすでにDavut Gürbüzの回答を提出しました.彼は私を正しい方向に向けました.
とにかく、実際の問題を説明する私自身の答えをチェックしてください。