Что самый надежный путь состоит в том, чтобы создать пользовательский журнал событий и источник события во время установки.Net Service

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

25
задан abatishchev 5 June 2011 в 10:40
поделиться

10 ответов

Лучшая рекомендация - не использовать проект установки в Visual Studio. Это имеет очень серьезные ограничения. У меня были очень хорошие результаты с WiX

5
ответ дан Albert 28 November 2019 в 21:09
поделиться

Добавление пустого ключа реестра в HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ eventlog \ Application \ MY_CUSTOM_SOURCE_NAME_HERE, кажется, работает нормально.

0
ответ дан Ray Hulha 28 November 2019 в 21:09
поделиться

Следуя предложению Хельба , я решил эту проблему. Уничтожение установщика журнала событий по умолчанию в точке, указанной в его примере, не позволило установщику автоматически зарегистрировать мою службу Windows в журнале событий приложений.

Слишком много времени было потеряно, пытаясь решить эту неприятную причуду. Спасибо за миллион!

FWIW, я не мог изменить код в своем сгенерированном дизайнером классе ProjectInstaller, не заставляя VS беспокоиться о модах. Я удалил сгенерированный дизайнером код и вручную вошел в класс.

0
ответ дан 28 November 2019 в 21:09
поделиться

Я столкнулся с некоторым странным поведением, потому что пытался зарегистрировать источник событий с тем же именем, что и служба, которую я запускал.

Я заметил, что для DisplayName также установлено то же имя, что и для вашего источника событий.

При запуске службы мы обнаружили, что Windows зарегистрировала запись «Служба успешно запущена» в журнале приложений с источником в качестве DisplayName. Похоже, это привело к регистрации имени приложения в журнале приложений.

В моем классе журнала событий я позже попытался зарегистрировать Имя приложения как источник с другим журналом событий, но когда дело дошло до добавления новых записей журнала событий, они всегда добавлялись в Приложение. войти.

Я также несколько раз получал сообщение «Описание для идентификатора события (0) в источнике».

В качестве обходного пути я просто зарегистрировал источник сообщения с немного другим именем для DisplayName, и с тех пор он работает. Стоит попробовать это, если вы еще этого не сделали.

0
ответ дан John Sibly 28 November 2019 в 21:09
поделиться

Проблема возникает из-за installutil, который по умолчанию регистрирует источник событий с именем ваших сервисов в EventLog «Приложение». Я все еще ищу способ остановить это, делая это дерьмо. Было бы здорово, если бы кто-то мог повлиять на поведение installutil: (

0
ответ дан nojetlag 28 November 2019 в 21:09
поделиться

Я также следовал предложению helb , за исключением того, что я в основном использовал классы, сгенерированные стандартным конструктором (объекты по умолчанию "ServiceProcessInstaller1" и "ServiceInstaller1"). Я решил опубликовать это, так как это немного более простая версия; а также потому, что я работаю в VB, и людям иногда нравится видеть VB-путь.

Как сказал tartheode , вам не следует изменять сгенерированный дизайнером класс ProjectInstaller в файле ProjectInstaller.Designer.vb , но вы можете изменить код в файле ProjectInstaller.vb . После создания обычного ProjectInstaller (с использованием стандартного механизма «Add Installer») единственное изменение, которое я сделал, было в New () класса ProjectInstaller. После обычного вызова InitializeComponent () я вставил этот код:

  ' remove the default event log installer 
  Me.ServiceInstaller1.Installers.Clear()

  ' Create an EventLogInstaller, and set the Event Source and Event Log      
  Dim logInstaller As New EventLogInstaller
  logInstaller.Source = "MyServiceName"
  logInstaller.Log = "MyCustomEventLogName"

  ' Add the event log installer
  Me.ServiceInstaller1.Installers.Add(logInstaller)

Это сработало, как и ожидалось, в том, что установщик не создал источник событий в журнале приложений, а скорее созданный в новом пользовательском файле журнала.

Тем не менее, я облажался настолько, что у меня была небольшая путаница на одном сервере. Проблема с пользовательскими журналами заключается в том, что если существует имя источника события, связанное с неправильным файлом журнала (например, журнал «Приложение» вместо вашего нового пользовательского журнала), то сначала необходимо удалить имя источника; затем машина перезагрузилась; тогда источник может быть создан с привязкой к правильному журналу. Справка Microsoft четко заявляет (в описании класса EventLogInstaller ):

Метод Install генерирует исключение, если свойство Source соответствует имени источника, зарегистрированному для другого журнала событий. на компьютере.

Следовательно, у меня также есть эта функция в моей службе, которая вызывается при запуске службы:

   Private Function EventLogSourceNameExists() As Boolean
      'ensures that the EventSource name exists, and that it is associated to the correct Log 

      Dim EventLog_SourceName As String = Utility.RetrieveAppSetting("EventLog_SourceName")
      Dim EventLog_LogName As String = Utility.RetrieveAppSetting("EventLog_LogName")

      Dim SourceExists As Boolean = EventLog.SourceExists(EventLog_SourceName)
      If Not SourceExists Then
         ' Create the source, if it does not already exist.
         ' An event log source should not be created and immediately used.
         ' There is a latency time to enable the source, it should be created
         ' prior to executing the application that uses the source.
         'So pass back a False to cause the service to terminate.  User will have 
         'to re-start the application to make it work.  This ought to happen only once on the 
         'machine on which the service is newly installed

         EventLog.CreateEventSource(EventLog_SourceName, EventLog_LogName)  'create as a source for the SMRT event log
      Else
         'make sure the source is associated with the log file that we want
         Dim el As New EventLog
         el.Source = EventLog_SourceName
         If el.Log <> EventLog_LogName Then
            el.WriteEntry(String.Format("About to delete this source '{0}' from this log '{1}'.  You may have to kill the service using Task Manageer.  Then please reboot the computer; then restart the service two times more to ensure that this event source is created in the log {2}.", _
            EventLog_SourceName, el.Log, EventLog_LogName))

            EventLog.DeleteEventSource(EventLog_SourceName)
            SourceExists = False  'force a close of service
         End If
      End If
      Return SourceExists
   End Function

Если функция возвращает False, код запуска службы просто останавливает службу. Эта функция в значительной степени гарантирует, что вы в конечном итоге получите правильное имя источника события, связанное с правильным файлом журнала событий. Возможно, вам придется перезагрузить машину один раз; и вам, возможно, придется попробовать запустить службу более одного раза.

2
ответ дан Tod Flak 28 November 2019 в 21:09
поделиться

Я должен согласиться со stephbu о «странных состояниях», в которые попадает журнал событий, я сталкивался с этим раньше. Если бы я догадался, некоторые из ваших трудностей лежат там.

Однако лучший из известных мне способов ведения журнала событий в приложении - это использование TraceListener. Вы можете настроить их через app.config службы:

http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogtracelistener.aspx

В середине этой страницы есть раздел, в котором описано, как использовать свойство EventLog для указания EventLog, в который вы хотите записать.

Надеюсь, что это помогает.

2
ответ дан Zachary Yates 28 November 2019 в 21:09
поделиться

Несколько вещей здесь

Создание журналов событий и источников на лету довольно неодобрительно. в первую очередь из-за прав, необходимых для выполнения действия - вы действительно не хотите благословлять свои приложения этой силой.

Более того, если вы удаляете журнал событий или источник, запись только действительно удаляется при перезагрузке сервера, поэтому вы можете войти в странное состояние, если удаляете и воссоздаете записи, не подпрыгивая. Существует также множество неписаных правил о конфликтах имен из-за способа хранения метаданных в реестре.

Рекомендуемый путь - это скрипт установщика и installutil или подпрограмма установки Windows.

7
ответ дан stephbu 28 November 2019 в 21:09
поделиться

Класс ServiceInstaller автоматически создает EventLogInstaller и помещает его в собственную коллекцию установщиков.

Попробуйте этот код:

ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
serviceProcessInstaller.Password = null;
serviceProcessInstaller.Username = null;
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;

// serviceInstaller
ServiceInstaller serviceInstaller = new ServiceInstaller();
serviceInstaller.ServiceName = "MyService";
serviceInstaller.DisplayName = "My Service";
serviceInstaller.StartType = ServiceStartMode.Automatic;
serviceInstaller.Description = "My Service Description";
// kill the default event log installer
serviceInstaller.Installers.Clear(); 

// Create Event Source and Event Log     
EventLogInstaller logInstaller = new EventLogInstaller();
logInstaller.Source = "MyService"; // use same as ServiceName
logInstaller.Log = "MyLog";

// Add all installers
this.Installers.AddRange(new Installer[] {
   serviceProcessInstaller, serviceInstaller, logInstaller
});
25
ответ дан JP Hellemons 28 November 2019 в 21:09
поделиться

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

1
ответ дан 28 November 2019 в 21:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: