Подтвердить что ты не робот

Как захватить вывод консоли из службы С#?

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

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

Update:

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

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

4b9b3361

Ответ 1

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

Ответ 2

В общем, вам следует избегать записи диагностической информации непосредственно в Консоль, журнал событий, 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. Поэтому предпочитайте трассировку для отладки, если вы хотите, чтобы выход был доступен в версиях выпуска.

Ответ 3

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

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);

Затем найдите записи в журнале событий приложений (Administrative Tools → Event Viewer), где Source = "MyService".

Ответ 4

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

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

Ответ 5

используйте debug.writeline и используйте sysinternals debugview?

Ответ 6

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

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

Ответ 7

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

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

  • Используйте редактор реестра для изменения 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.

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

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

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