Более простой способ отладки службы Windows - PullRequest
313 голосов
/ 24 сентября 2008

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

Ответы [ 28 ]

9 голосов
/ 11 июня 2013

Используйте библиотеку TopShelf .

Создайте консольное приложение, затем настройте настройки в главном

class Program
    {
        static void Main(string[] args)
        {
            HostFactory.Run(x =>
            {

                // setup service start and stop.
                x.Service<Controller>(s =>
                {
                    s.ConstructUsing(name => new Controller());
                    s.WhenStarted(controller => controller.Start());
                    s.WhenStopped(controller => controller.Stop());
                });

                // setup recovery here
                x.EnableServiceRecovery(rc =>
                {
                    rc.RestartService(delayInMinutes: 0);
                    rc.SetResetPeriod(days: 0);
                });

                x.RunAsLocalSystem();
            });
        }
}

public class Controller
    {
        public void Start()
        {

        }

        public void Stop()
        {

        }
    }

Чтобы отладить ваш сервис, просто нажмите F5 в visual studio.

Чтобы установить службу, введите cmd "console.exe install"

После этого вы можете запускать и останавливать службу в диспетчере служб Windows.

8 голосов
/ 24 сентября 2008

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

Два варианта, которые я использовал в прошлом:

  • Используйте GFlags (в инструментах отладки для Windows), чтобы настроить постоянный отладчик для процесса. Он существует в разделе реестра «Параметры выполнения файла изображения» и невероятно полезен. Я думаю, что вам нужно настроить параметры службы, чтобы включить «Взаимодействие с рабочим столом». Я использую это для всех типов отладки, а не только для служб.
  • Другой вариант - немного отделить код, чтобы сервисная часть была взаимозаменяемой при обычном запуске приложения. Таким образом, вы можете использовать простой флаг командной строки и запускать как процесс (а не как службу), что значительно упрощает отладку.

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

5 голосов
/ 01 июля 2011

Мне нравится иметь возможность отлаживать каждый аспект моего сервиса, включая любую инициализацию в OnStart (), и в то же время выполнять его с полным поведением сервиса в рамках SCM ... без режима "console" или "app" ,

Я делаю это, создавая в том же проекте второй сервис для отладки. Служба отладки, когда она запускается как обычно (то есть в плагине MMC служб), создает процесс узла службы. Это дает вам процесс присоединения отладчика, даже если вы еще не запустили свой реальный сервис. После присоединения отладчика к процессу запустите реальную службу, и вы сможете взломать ее в любом месте жизненного цикла службы, включая OnStart ().

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

подробности:

1) Предполагая, что вы реализуете MyService, также создайте MyServiceDebug. Добавьте оба к массиву ServiceBase в Program.cs примерно так:

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new MyService(),
            new MyServiceDebug()
        };
        ServiceBase.Run(ServicesToRun);
    }

2) Добавьте реальный сервис И сервис отладки в установщик проекта для сервисного проекта:

enter image description here

Обе службы (реальная и отладочная) включаются при добавлении выходных данных проекта службы в проект установки для службы. После установки обе службы появятся в плагине MMC service.msc.

3) Запустите службу отладки в MMC.

4) В Visual Studio присоедините отладчик к процессу, запущенному службой отладки.

5) Запустите реальный сервис и наслаждайтесь отладкой.

5 голосов
/ 24 сентября 2008

Когда я пишу сервис, я помещаю всю логику сервиса в проект dll и создаю два «хоста», которые вызывают этот dll, один - сервис Windows, а другой - приложение командной строки.

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

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

4 голосов
/ 24 сентября 2008

Как насчет Debugger.Break () в первой строке?

4 голосов
/ 24 сентября 2008

При разработке и отладке службы Windows я обычно запускаю ее как консольное приложение, добавляя параметр запуска / console и проверяя его. Делает жизнь намного проще.

static void Main(string[] args) {
    if (Console.In != StreamReader.Null) {
        if (args.Length > 0 && args[0] == "/console") {
            // Start your service work.
        }
    }
}
2 голосов
/ 24 сентября 2008

Для отладки служб Windows я объединяю GFlags и файл .reg, созданный regedit.

  1. Запустите GFlags, указав exe-имя и vsjitdebugger
  2. Запустите regedit и перейдите к месту, где GFlags устанавливает свои параметры
  3. Выберите «Ключ экспорта» из меню-файла
  4. Сохраните этот файл где-нибудь с расширением .reg
  5. В любое время, когда вы хотите отладить службу: дважды щелкните по файлу .reg
  6. Если вы хотите прекратить отладку, дважды щелкните второй файл .reg

Или сохраните следующие фрагменты и замените servicename.exe на нужное имя исполняемого файла.


debugon.reg:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe]
"GlobalFlag"="0x00000000"
"Debugger"="vsjitdebugger.exe"

debugoff.reg:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe]
"GlobalFlag"="0x00000000"
1 голос
/ 24 сентября 2008

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

При запуске службы я проверяю параметр командной строки "/ debug". Если служба вызывается с этим параметром, я не делаю обычного запуска службы, а вместо этого запускаю все прослушиватели и просто отображаю окно сообщения «Выполняется отладка, нажмите ОК для завершения».

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

В VS я просто добавлю / отладлю в качестве параметра отладки и сразу запущу служебную программу.

Таким образом, я могу легко отлаживать для большинства мелких добрых задач. Конечно, некоторые вещи все равно нужно будет отлаживать как сервис, но для 99% этого достаточно.

1 голос
/ 24 ноября 2008
#if DEBUG
    System.Diagnostics.Debugger.Break();
#endif
1 голос
/ 20 мая 2015

Для устранения неполадок в существующей программе Windows Service используйте «Debugger.Break ()», как предложили другие парни.

Для новой программы Windows Service я бы предложил использовать метод Джеймса Майкла Хейра http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable-windows-service-template-redux.aspx

...