Как зарегистрировать автоматически регистрируемое свойство EventLog службы Windows в журнале, отличном от журнала приложений?

В настоящее время я создаю службу Windows и только что понял (благодаря этому ответу), как настроить установщик службы, чтобы для создания настраиваемого источника журнала событий во время установки. Как я уже понял, для регистрации этих настраиваемых источников журнала событий требуются повышенные привилегии. И поэтому регистрация происходит во время установки - ведь установка сервиса всегда выполняется с повышенными привилегиями. Все идет нормально.

Однако я не на 100% удовлетворен этим решением, потому что, как указано в документации _ 1_:

Свойство Log для этого источника устанавливается конструктором ServiceInstaller для журнала приложений компьютера.

И я не этого хочу. Я хочу, чтобы события регистрировались в настраиваемом журнале MyCustomLog. Более того, я не могу просто установить ServiceBase.EventLog.Log моей службы на «MyCustomLog». Как я могу индивидуально установить EventLog.Log для моей службы? И где мне это делать?

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

введите описание изображения здесь

Он не заменяет настраиваемый журнал событий, поскольку события по-прежнему регистрируются в журнале приложений, но он позволяет мне иметь обзор определенных событий, произошедших в моей службе, точно так же, как это было бы в настраиваемом журнале событий. Итак, как мне программно создавать такие настраиваемые представления? Это возможно? И если да, то где мне их создавать? Требуются ли для создания повышенные привилегии, поэтому его нужно делать внутри ServiceInstaller? Или это можно легко сделать в конструкторе моего сервиса?

Буду признателен за ответы относительно осуществимости обоих подходов!


person Pete Hilde    schedule 29.04.2020    source источник
comment
IIRC, вы можете унаследовать от ServiceInstaller и очистить коллекцию Installers после запуска конструктора базового класса. Затем вы можете добавить EventLogInstaller, который вы хотели бы добавить. Единственное, что нужно сделать, это правильно установить Source (потому что установка его с помощью ServiceName в установщике не сработает). Я мог бы поклясться, что написал здесь ответ об этом много лет назад, но не могу его найти. Возможно, я и здесь пропустил шаг или два, но я знаю, что это работает.   -  person Damien_The_Unbeliever    schedule 29.04.2020


Ответы (1)


Подробнее см. здесь. Следующее должно работать, как минимум, в Visual Studio 2017 и Visual Studio 2019.

  1. В обозревателе решений Visual Studio дважды щелкните компонент службы, т. Е. Компонент, производный от _ 1_. Компонент откроется в представлении [Дизайн].
  2. В открытом представлении [Дизайн] откройте сетку свойств, нажав F4 (или в меню «Просмотр | Окно свойств»).
  3. В сетке свойств установите для свойства AutoLog значение false. Это предотвратит запись событий по умолчанию в журнал приложений Windows.
  4. Если вы еще этого не сделали, щелкните правой кнопкой мыши в любом месте представления [Дизайн] компонента службы и выберите пункт меню Добавить установщик. Это добавляет к вашему решению компонент с именем ProjectInstaller по умолчанию.
  5. Обратите внимание, что новый ProjectInstaller автоматически открывается в соответствующем представлении [Дизайн]. Чтобы перейти к его коду, щелкните правой кнопкой мыши файл ProjectInstaller.cs в обозревателе решений и выберите пункт меню «Просмотреть код».
  6. Измените содержимое этого файла, чтобы оно выглядело следующим образом. Это обновит EventLogInstaller, чтобы использовать произвольное имя журнала по вашему выбору.
    using System.ComponentModel;
    using System.Configuration.Install;
    using System.Diagnostics;

    namespace YourProjectNamespace
    {
        [RunInstaller(true)]
        public partial class ProjectInstaller : Installer
        {
            public ProjectInstaller()
            {
                InitializeComponent();

                EventLogInstaller installer = FindInstaller(this.Installers);
                if (installer != null)
                {
                    installer.Log = "YourEventLogName"; // enter your event log name here
                }
            }

            private EventLogInstaller FindInstaller(InstallerCollection installers)
            {
                foreach (Installer installer in installers)
                {
                    if (installer is EventLogInstaller)
                    {
                        return (EventLogInstaller)installer;
                    }

                    EventLogInstaller eventLogInstaller = FindInstaller(installer.Installers);
                    if (eventLogInstaller != null)
                    {
                        return eventLogInstaller;
                    }
                }
                return null;
            }
        }
    }
  1. Последний шаг - привязать сервисный компонент к настраиваемому журналу событий, который вы назвали на шаге 6. Для этого щелкните правой кнопкой мыши сервисный компонент в обозревателе решений и выберите пункт меню «Просмотреть код». Обновите конструктор до следующего:
    public YourServiceName()
    {
        InitializeComponent();

        // This ties the EventLog member of the ServiceBase base class to the
        // YourEventLogName event log created when the service was installed.
        EventLog.Log = "YourEventLogName";
    }
  1. При установке службы в системе должен быть создан YourEventLogName. Если средство просмотра событий уже открыто, вам, вероятно, придется его обновить. Если он все еще не виден, возможно, вам нужно что-то записать в него (подробностей я не помню). В любом случае, чтобы записать информацию журнала в настраиваемый журнал событий из вашей службы, используйте член EventLog компонента службы, например,
    protected override void OnStart(string[] args)
    {
        EventLog.WriteEntry("The service was started successfully.", EventLogEntryType.Information);
    }

    protected override void OnStop()
    {
        EventLog.WriteEntry("The service was stopped successfully.", EventLogEntryType.Information);
    }

    protected override void OnShutdown()
    {
        EventLog.WriteEntry("The service was shutdown successfully", EventLogEntryType.Information);
    }
person Matt Davis    schedule 02.05.2020
comment
Я выполняю все ваши шаги, но, к сожалению, события все еще записываются в журнал приложений. Я даже записал в журнал значения свойств AutoLog и EventLog.Log, чтобы убедиться, что что-то настроено неправильно, но для AutoLog установлено значение false, а для EventLog.Log - MyCustomLog. Я также воссоздал проект службы Windows, чтобы увидеть, могут ли внесенные мной изменения повлиять на использование настраиваемого журнала событий, но это тоже не помогло. Есть ли что-то еще, что я должен учитывать при настройке службы? - person Pete Hilde; 04.05.2020
comment
Я понял, что перезапуск моей системы приводит к появлению событий в указанном мной журнале. Это где-то задокументировано или я что-то неправильно настроил? Если это задокументировано, я бы рекомендовал добавить ссылку на документацию, а также аннотацию для перезапуска системы, если текущий ответ не принесет ожидаемого успеха. - person Pete Hilde; 04.05.2020
comment
Я забыл упомянуть, что раньше я уже работал с EventLog.Source и теперь сопоставил его с новым журналом, поэтому мне пришлось перезагрузить компьютер, чтобы изменения вступили в силу, как описано здесь: docs.microsoft.com/en-us/dotnet/ api / - person Pete Hilde; 04.05.2020