Вопрос

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

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

Обновлять:

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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».

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

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

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

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

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

Вот как я просмотрел консольный вывод службы, работающей под 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 обратно на исходное значение.Затем снимите флажок «Разрешить службе взаимодействовать с рабочим столом» в свойствах службы и перезапустите службу.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top