2008-10-14 5 views
18

У нас есть служба C#, которая развертывается в удаленной системе клиентов. Приложение записывает значительную часть «диагностической» информации на консоль (т. Е. Console.WriteLine()). Служба не «делает то, что должна». Как мы можем захватить вывод консоли из службы в другом приложении?Как захватить вывод консоли из службы C#?

Версия WinForm приложение может быть загружено в месте нахождения клиента. Это, к сожалению, работает правильно.

Update:

Мы можем изменить Изменение службы, но предпочли бы не делать серьезные изменения в это время.

Мы также регистрируемся в MSMQ, но только для «важных» событий. Эта служба действительно взаимодействует с MSMQ для нормальной работы. Или, по крайней мере, это должно быть. Кажется, что служба не тянет элементы из MSMQ, когда версия WinForm делает. Поэтому писать сообщения, которые идут на консоль, могут быть проблематичными.

ответ

31

Возможно ли изменить код услуги на всех? Если это так, то использование Console.SetOut для записи в файл будет самым очевидным первым портом вызова. Затем перейдите к использованию соответствующей библиотеки журналов для следующего выпуска :)

+2

Использование Console.SetOut было минимально возможным изменением, которое дало достаточно информации для определения проблемы с сервисом. – 2008-10-14 16:04:09

3

Я бы не использовал Console.WriteLine вообще из Window Service. Вероятно, вы должны зарегистрировать эти ошибки в файле журнала.

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

3

использовать debug.writeline и использовать sysinternals debugview?

+1

или log4net в следующий раз и настроить назначение. – kenny 2008-10-14 16:54:52

5

У вас есть множество вариантов; перенаправление вывода консоли в файл и использование надлежащей библиотеки протоколирования, как упомянуто, являются двумя хорошими. Вот средний вариант: напишите в журнал событий.

EventLog log; 
string logsource = "MyService"; 

// execute once per invocation 
if (!System.Diagnostics.EventLog.SourceExists(logsource)) 
{ 
    System.Diagnostics.EventLog.CreateEventSource(
     logsource, "Application"); 
} 
log = new EventLog(); 
log.Source = logsource; 
log.Log = "Application"; 

// replace console logging with this 
log.WriteEntry(message, EventLogEntryType.Information); 

Тогда посмотрите записи в журнале событий приложений (Администрирование -> Просмотр событий), где Source = "MyService".

12

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

Например, вы можете заменить все Console.WriteLine на Trace.WriteLine (*). После этого вы можете перенаправить вывод в консоль, файл или в другом месте путем изменения файла конфигурации приложения: например, для вывода на консоль, используйте ConsoleTraceListener, что-то вроде:

<configuration> 
    <system.diagnostics> 
    <trace autoflush="false" indentsize="4"> 
     <listeners> 
     <add name="configConsoleListener" 
      type="System.Diagnostics.ConsoleTraceListener" /> 
     </listeners> 
    </trace> 
    </system.diagnostics> 
</configuration> 

Во время отладки, вы получите ваш вывода на консоли - на сайте клиента вы настроили его для перенаправления вывода трассировки в файл, в журнал событий или аналогичный.

Еще лучше, используйте стороннюю структуру ведения журнала (я бы рекомендовал Log4Net), которая даст вам больше возможностей, чем System.Diagnostics.Trace.

(*) Trace.Write/Trace.WriteLine такие же, как Debug.Write/Debug.WriteLine, за исключением того, что последние только скомпилированы, если определен символ DEBUG. Поэтому предпочитайте Trace to Debug, если вы хотите, чтобы выход был доступен в сборках Release.

1

Я нашел this post на MSDN, который связывает вывод Консоли с богатым текстовым полем, работал для меня очень быстро и легко.

Он переопределяет WriteLine и может быть расширен, чтобы переопределить другие методы.

1

Вот как я просмотрел вывод консоли службы под управлением Windows 7. Это может помочь, если вы абсолютно не можете изменить исходный код службы для входа в файл.

  1. Запустить services.msc и отредактировать свойства сервиса. На вкладке «Вход в систему» ​​установите флажок «Разрешить услугу взаимодействовать с рабочим столом».

  2. Используйте редактор реестра для изменения ImagePath вашей службы: перейдите в HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ services \ [ваше имя службы] и Редактировать ImagePath. Добавить cmd.exe /c в начало строки ImagePath. Так что если ваш оригинальный ImagePath - c:\myService\myservice.exe, ваш новый ImagePath должен быть cmd.exe /c c:\myService\myservice.exe.

  3. Запустите службу. Вы должны получить всплывающее окно под названием «Обнаружение интерактивных служб». Выберите «Просмотреть сообщение». Ваш экран должен переключать контексты и отображать окно консоли. По завершении нажмите кнопку «Вернуться сейчас».

  4. По завершении отладки измените ImagePath на исходное значение. Затем снимите флажок «Разрешить службу для взаимодействия с рабочим столом» в свойствах службы и перезапустите службу.

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