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

    }