Почему служба Windows не вызывает метод OnStart? - PullRequest
0 голосов
/ 27 июня 2018

Я создал приложение службы Windows, которое имеет метод OnStart. Метод считывает путь из файла app.config , создает объект, а затем служба записывает переопределенный метод ToString() объекта в файл с StreamWriter.

Это работает, когда я вручную запускаю эту службу с " net start ". Итак, вызван метод OnStart, объект создал и записал свой метод ToString в файл.

Я установил его как автоматический запущенный сервис при запуске Windows. Моя проблема в том, что этот OnStart метод не вызывается после запуска службы Windows. Поэтому я думаю, что когда 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);
    }

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Если средство просмотра событий показывает, что служба была успешно запущена, ваш OnStart был вызван и возвращен из. Как вы определили, что это не называется? Я думаю по тому, что ваш файл не был записан. Проблема, скорее всего, не в том, что ваш OnStart не вызывается, а в том, что WriteToFile не удалось и / или он был записан в другое место (например, вы используете относительный путь, который отличается или недоступен во время запуска). Я предлагаю следующую процедуру, чтобы проверить это:

  • Используйте System.Diagnostics.Trace.WriteLine для вывода сообщений отладки в OnStart
  • Загрузите и установите / скопируйте приложение DebugView от Microsoft.
  • Настройте DebugView на 1) Capture Global 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.

0 голосов
/ 05 июля 2018

Так как ваша служба запускается, когда вы пытаетесь запустить ее из командной строки, используя 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);
}

После добавления этого кода в службу повторно разверните его, перезапустите систему и проверьте журнал событий. Как минимум, вы должны увидеть сообщение, зарегистрированное при запуске службы.

0 голосов
/ 27 июня 2018

Как вы уже упоминали при запуске Windows, вы поместили свой исполняемый файл в папку автозагрузки? Если да, то это не сработает. Вам необходимо установить службу в диспетчере служб Windows. Описание Microsoft для установки сервисов

...