C# windows服务异常行为
我使用C# windows服务异常行为,c#,.net,windows-services,C#,.net,Windows Services,我使用eventLog和FileSystemWatcher实现了windows服务,它查找特定目录中的更改并将消息写入MyLog 奇怪的事情1: 我通过installUtil.exe安装它(因为VS2012没有安装程序模板),在某些情况下,当我转到“服务”并启动服务时,我会得到: 本地计算机上的[service name]服务已启动,然后停止。如果其他服务或程序未使用某些服务,则它们会自动停止 我已经看过了。这篇文章的两个答案是为什么会这样: 1) OnStart()方法中没有开始的线程。 我使
eventLog
和FileSystemWatcher
实现了windows服务,它查找特定目录中的更改并将消息写入MyLog
奇怪的事情1:我通过installUtil.exe安装它(因为VS2012没有安装程序模板),在某些情况下,当我转到“服务”并启动服务时,我会得到: 本地计算机上的[service name]服务已启动,然后停止。如果其他服务或程序未使用某些服务,则它们会自动停止 我已经看过了。这篇文章的两个答案是为什么会这样: 1)
OnStart()方法中没有开始的线程。
我使用设计器并在属性窗口中设置大多数属性,我从未手动启动过任何线程,但在某些情况下一切正常,所以我认为情况并非如此
2) OnStart()方法中发生异常。我想不是这样,因为我没有改变密码。我只是卸载、构建并再次安装同一个服务,在某些情况下它会运行,在某些情况下则不会
当我被这个东西卡住了2个小时后,我注意到eventLog
的Source
属性太长:“filemonitoringservices”。我把它改为“MonitorSource”,一切都开始工作了。然后我重新安装了好几次,得到了与上面相同的警告。我再次更改了Source
属性,现在服务运行。
这是第一件奇怪的事
奇怪的事情2:更糟。即使它运行时只记录OnStart()
和OnStop()
方法,我的意思是fileSystemWatcher事件处理程序永远不会执行。这是奇怪的,因为今天我重新安装了这项服务百倍,三倍,它是工作的,但在我重新安装后,它停止了。我还没有在重新安装之间更改代码
下面是我的类(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) 如果显示消息(当我想启动服务时):
我需要更改eventLog
的Source
属性,重建并重新安装。而这个消息不会出现;下次见
2) 我有以下文件夹层次结构:images/prod images
<代码>图像
和产品图像
目录都包含图像文件。当服务运行时,我从prod images
文件夹更改图像时,消息会按照我的要求写入日志,并更新数据库。但在一次事件之后,服务停止!(我检查了3次)。当我重新启动它并重复几次时,它会更新数据库,写入日志,并在我得到的3d时间
The [service name] service on local computer started and then stopped. ....
但这不是最好的部分)如果我更改images
目录中的图像,我可以多次这样做,并且服务不会停止。(只有来自images/prod images
的图像才会绑定到数据库中的条目)
那么,这个特性是否与数据库访问有关
编辑2:在visual studio中,我使用DEBUG->attachtoprocess
调试服务。我设置断点并更改图像。事件处理程序第一次完美执行时:更新数据库并写入日志消息。但随后我继续按F11键(单步执行),这个事件处理程序第二次执行。排队
var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value);
我得到“FormatException
未处理”。在此之后,我停止调试,服务停止!就是这样:异常发生在事件处理程序中
你知道为什么它会执行第二次吗?谢谢
p.S.我已经提交了Davut Gürbüz的答案,因为他为我指明了正确的方向。
无论如何,请查看我自己解释实际问题的答案。如果出现“开始-停止”错误,这意味着您在构造函数中有错误
在你的身体里放一个试球。您可以在catch块中将错误记录到eventlog
除此之外,我还创建了一个main方法,并将win服务作为一个控制台应用程序启动。如果我在我的主方法中得到一个服务实例,我也可以调试它
//You should select Console Application from Application properties
static void Main(string[] args)
{
MyWindowsService service = new MyWindowsService();
if (Environment.UserInteractive)
{
service.OnStart(args);
Console.WriteLine("Press any key to stop program");
Console.Read();
service.OnStop();
}
else
{
ServiceBase.Run(service);
}
}
希望有帮助更改事件处理程序方法
的原因是因为我在监视图像
文件夹中包含的子目录。此事件处理程序正在监视所有LastWrite
事件
因此,当我在images/prod images
目录中更改图像时,此处理程序会对图像更改和文件夹更改做出反应
在这种情况下,我可以将监视路径更改为prod images
,或者在更新数据库时插入if
语句
这样一个愚蠢的错误花了我几天时间才发现。)这是打字错误吗<代码>eventLog.EnableRaisingEvents=true而不是
fileWatcher.EnableRaisingEvents=true代码>是的,这是一个打字错误,对不起,现在我没有得到一个开始-停止错误。在我更改映像后,服务立即停止(并且日志中没有条目,数据库也没有更新)。我试图在ctor、OnStart和OnStop方法中添加try/catch块,并将异常记录到MyLog中,但不起作用。服务会像以前一样停止。所以只需执行我的第二个选项,使用win service作为控制台应用程序,在main方法中创建service和console.readkey以不退出main。通过这种方式,您可以将win服务作为控制台应用程序运行。然后测试出错的地方。Windows事件日志中是否有错误?即使它们通常也没有显示确切的原因,所以只有s
//You should select Console Application from Application properties
static void Main(string[] args)
{
MyWindowsService service = new MyWindowsService();
if (Environment.UserInteractive)
{
service.OnStart(args);
Console.WriteLine("Press any key to stop program");
Console.Read();
service.OnStop();
}
else
{
ServiceBase.Run(service);
}
}