为什么Windows服务不调用OnStart方法?

时间:2018-06-27 07:51:37

标签: c# .net windows service

我创建了一个具有OnStart方法的Windows服务应用程序。该方法将从 app.config 文件读取路径,创建一个对象,然后服务将该对象的覆盖的ToString()方法写入具有StreamWriter的文件中。

当我使用“ 网络启动”手动启动此服务时,此方法有效。因此,OnStart方法被调用,对象被创建并将其ToString方法写入文件。

当Windows启动时,我将其设置为自动运行的服务。 我的问题是Windows启动服务后,没有调用此OnStart方法。因此,我认为,当Windows在启动时开始运行服务时,它将启动我的服务,只是不调用OnStart方法。

有人有相同的问题还是有人有解决方案?

OnStart方法:

protected override void OnStart(string[] args)
    {
        filePath = configReader.ReadConfig("FilePath");
        DateEvent dateEvent = new DateEvent(DateTime.Now, TimeLoggerCore.Events.STARTUP.ToString());
        writer.WriteToFile(dateEvent, filePath, true, false);
    }

构造函数:

public TimeLoggerService()
    {
        InitializeComponent();
        configReader = new AppConfigReader();
        writer = new CSVWriter();
    }

Program.cs:

static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            new TimeLoggerService()
        };
        ServiceBase.Run(ServicesToRun);
    }

4 个答案:

答案 0 :(得分:0)

如果事件查看器显示服务已成功启动,则您的OnStart已被调用并已从中返回。您如何确定未致电?我猜是因为您的文件尚未写入。问题可能不是您的OnStart没有被调用,而是WriteToFile失败和/或它被写入了其他位置(例如,您使用的相对路径在启动过程中是不同的或不可用的)。我建议按照以下步骤进行检查:

  • 使用System.Diagnostics.Trace.WriteLine在OnStart中输出调试消息
  • 从Microsoft下载并安装/复制DebugView应用程序。
  • 将DebugView配置为1)捕获全局Win32,2)使用您的应用程序名称在进程名称上设置过滤器,以及3)在启动时启用日志记录(请参阅DebugView帮助)。

对所有设置进行一点实验,以确保它们按预期工作。

最后,还要在OnStart文档中注意这一点:

Do not use the constructor to perform processing that should be in OnStart. Use OnStart to handle all initialization of your service. The constructor is called when the application's executable runs, not when the service runs. The executable runs before OnStart. When you continue, for example, the constructor is not called again because the SCM already holds the object in memory. If OnStop releases resources allocated in the constructor rather than in OnStart, the needed resources would not be created again the second time the service is called.

答案 1 :(得分:0)

由于当您尝试使用net.exe start [ServiceName]从命令行启动服务时启动了服务,但是在Windows启动时无法启动,因此启动过程中可能遇到异常。

在构建和使用自定义Windows服务时要注意的一件事是Windows事件日志对于跟踪问题很有帮助。当服务中发生错误时,值得将该错误记录在事件日志中。

在Visual Studio中调试正在运行的服务的另一个有用方法是启动服务,然后将VS调试器附加到该服务。

要获取一些Windows事件日志记录到服务中,我建议修改服务代码以记录其启动。请注意,对于该论坛,我在此处发布的内容得到了简化-我通常将所有日志记录代码放入一个单独的类中。这样,我可以在服务的整个生命周期内使用它。重要说明之一-确保使用适当的名称设置主服务类的ServiceName属性-这应在设计时在Visual Studio中的服务设计器“属性”窗口中完成。

private EventLog _eventLog;

/*
 * Use the EventId enumeration to store event IDs that will be written with events
 * to the Windows event log.
 */
enum EventId  
{
    ServiceStarting = 10,
    ServiceStartNormal = 100,
    ServiceStartFailure = 999;
}

protected override void OnStart(string[] args)
{
    try
    {
        // remember the event log
        _eventLog = EventLog;

        // log start
        LogMessage(_eventLog, "Service starting", EventLogEntryType.Information, EventId.ServiceStarting);

        filePath = configReader.ReadConfig("FilePath");
        DateEvent dateEvent = new DateEvent(DateTime.Now, TimeLoggerCore.Events.STARTUP.ToString());
        writer.WriteToFile(dateEvent, filePath, true, false);

        LogMessage(_eventLog, "Service started", EventLogEntryType.Information, EventId.ServiceStartNormal);
    }
    catch(Exception e)
    {
        LogMessage(_eventLog, e.ToString(), EventLogEntryType.Error, EventId.ServiceStartFailure);
    }
}

private static void LogMessage(EventLog eventLog, string message, EventLogEntryType entryType, EventId eventId)
{
    /*
     * If the event source we want to log doesn't exist, create it.
     * Note that this take admin privs, and creating the log source should be
     * done during service installation.  This is here as a secondary means
     * to create the log in the event that it doesn't already exist.
     */
    if (!EventLog.SourceExists(eventLog.Source)
    {
        EventLog.CreateEventSource(eventLog.Source, eventLog.Log);
    }
    eventLog.WriteEntry(message, entryType, (int) eventId);
}

将此代码添加到服务后,请重新部署它,重新启动系统,然后检查事件日志。至少您应该在服务启动时看到一条记录的消息。

答案 2 :(得分:0)

我的服务遇到了同样的问题,经过大量的挖掘,我发现未调用OnStop和OnStart的原因是Windows快速启动选项。 我登录了ServiceBase的所有可以覆盖的功能,并且在关闭笔记本电脑时调用的功能是OnPowerEvent,而不是OnStop。

My event log

当我重新启动Windows而不是关闭它们时,一切都按预期工作。

希望这对某人有帮助。

答案 3 :(得分:-3)

正如您提到的Windows启动一样,您是否将可执行文件放置在启动文件夹中?如果是,那将无法正常工作。您需要在Windows服务管理器中安装该服务。 Microsoft Description for installing services