Советы по отладке во время выполнения для Windows Service? - PullRequest
3 голосов
/ 11 мая 2011

У меня есть служба Windows, которая контролирует COM-порт, подключенный к оборудованию поставщика. Это очень загруженное оборудование, которое постоянно опрашивает другие устройства в сети (это «сеть» по витой паре RS485). Моему программному обеспечению необходимо эмулировать количество аппаратных устройств X на этом проводе, поэтому у меня есть многопоточная вещь с многоуровневым конечным автоматом, чтобы в любой момент отслеживать, где находится протокол связи.

Проблема со службой Windows (это моя первая, кстати, BTW) заключается в том, что вам нужна некоторая отладка, чтобы вы знали, что все работает правильно. Когда я впервые разрабатывал этот код конечного автомата / многопоточности, у меня была форма окна с RichTextBox, которая отображала символы ASCII, идущие назад и вперед в строке. Похоже, я не могу иметь такую ​​приятность GUI с сервисом. Я попытался открыть форму в службе через другую программу, которая отправляла служебные сообщения, полученные через обработчик OnCustomCommand (), но, похоже, это не сработало. Я проверил "Разрешить службе взаимодействовать с рабочим столом" и все. Я использовал методы Show () и Hide () моей формы отладки.

Полагаю, мне не нужно видеть всех отдельных персонажей, идущих по очереди, но человек, который наверняка был бы хорош (думаю, мне действительно нужно их видеть :-)). Так у кого-нибудь есть сумасшедшие идеи, которые могут мне помочь? Я не хочу перегружать систему каким-либо IPC, который не предназначен для большого объема данных, которые обязательно пройдут. Тем не менее, это будет только очень кратковременная отладка, только подтверждение того, что программа, ключ RS485-USB и аппаратное обеспечение работают.

Ответы [ 5 ]

4 голосов
/ 11 мая 2011

Используйте OutputDebugString для записи в буфер отладки, а затем используйте DebugView для его просмотра. Если вы работаете в Windows XP или более ранней версии, вы можете использовать PortMon , чтобы увидеть, как необработанные байты проходят через последовательный порт. Преимущество перед файлом журнала заключается в том, что накладных расходов очень мало, особенно когда вы его не смотрите. Вы даже можете запустить DebugView с другого компьютера и удаленно контролировать свой сервис.

2 голосов
/ 11 мая 2011

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

Редактировать:

Некоторые примеры:

class Worker : ServiceBase
{

#if(RELEASE)
        /// <summary>
        /// The Main Thread where the Service is Run.
        /// </summary>
        static void Main()
        {
            ServiceBase.Run(new Worker());
        }
#endif

#if(DEBUG)
        public static void Main(String[] args)
        {
            Worker worker = new Worker();
            worker.OnStart(null);
            Console.ReadLine();
            worker.OnStop();
        }
#endif

        // Other Service code
}
1 голос
/ 11 мая 2011

Вы можете записать вывод в файл журнала, а затем использовать другое приложение для просмотра этого файла. Этот вопрос о "tail" описывает несколько вариантов просмотра лог-файлов в Windows.

0 голосов
/ 14 мая 2011

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

Я создал приложение Windows Form с одной кнопкой и RichTextBox. Это приложение построило NamedPipeServerStream на своем конце. Задача Баттона заключалась в том, чтобы отправить «отладку вкл» (команда 128) или «отладку выкл» (129) в службу Windows. Начальное значение было «отладка». При нажатии кнопки в службу Windows была отправлена ​​команда 128 для включения отладки. В Windows Service это вызвало внутреннюю переменную, которая была истинной, плюс она соединилась с приложением Form с помощью NamedPipeClientStream и начала отправлять символы с BinaryWriter, как они были получены или отправлены на COM-порт. На стороне формы BackgroundWorker был создан для WaitForConnection () на конвейере. Когда он получил соединение, BinaryReader.ReadString () использовался для считывания данных из канала и передачи их в RichTextBox.

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

0 голосов
/ 12 мая 2011

Когда я работаю со службой Windows, я обычно создаю ее так, чтобы ее можно было запускать как службу или как простое старое приложение командной строки.Вы можете легко проверить, работаете ли вы как служба, проверив Environment.UserInteractive.Если это свойство имеет значение true, значит, вы работаете из командной строки.Если свойство имеет значение false, то вы работаете как сервис.Добавьте этот код в Program.cs и используйте его там, где вы обычно вызываете ServiceBase.Run (servicesToRun)

/// <summary>Runs the provided service classes.</summary>
/// <param name="servicesToRun">The service classes to run.</param>
/// <param name="args">The command-line arguments to pass to the service classes.</param>
private static void RunServices(IEnumerable<ServiceBase> servicesToRun, IEnumerable args)
{
    var serviceBaseType = typeof(ServiceBase);
    var onStartMethod = serviceBaseType.GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);
    foreach (var service in servicesToRun)
    {
        onStartMethod.Invoke(service, new object[] { args });
        Console.WriteLine(service.ServiceName + " started.");
    }

    Console.WriteLine("Press any key to exit.");
    Console.ReadKey();

    var onStopMethod = serviceBaseType.GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);
    foreach (var service in servicesToRun)
    {
        onStopMethod.Invoke(service, null);
        Console.WriteLine(service.ServiceName + " stopped.");
    }
}

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

...