Отладка службы Windows - PullRequest
       69

Отладка службы Windows

4 голосов
/ 22 июля 2011

Я создаю службу Windows и хочу ее отладить.

Это ошибка, которую я получаю при попытке отладки:

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

Я уже установил свой сервис, используя InstallUtil , но я все еще сталкиваюсь с проблемами.

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

РЕДАКТИРОВАТЬ: Нужно ли переустанавливать службу Windows каждый раз, когда мы вносим изменение или достаточно просто создать его?

Ответы [ 9 ]

4 голосов
/ 22 июля 2011

На этот вопрос есть отличный ответ, сделав сервис гибридом консоли / сервиса.См. ответ пользователя marc_s .Я не хочу дублировать ответ здесь.

4 голосов
/ 22 июля 2011

В вашем OnStart используйте что-то вроде этого:

#if DEBUG
if(!System.Diagnostics.Debugger.IsAttached)
   System.Diagnostics.Debugger.Launch();
#endif
4 голосов
/ 22 июля 2011

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

private static void Main(string[] args) {
    if (Environment.UserInteractive) {
        Console.WriteLine("My Service");
        Console.WriteLine();
        switch (args.FirstOrDefault()) {
        case "/install":
            ManagedInstallerClass.InstallHelper(new[] {Assembly.GetExecutingAssembly().Location});
            break;
        case "/uninstall":
            ManagedInstallerClass.InstallHelper(new[] {"/u", Assembly.GetExecutingAssembly().Location});
            break;
        case "/interactive":
            using (MyService service = new MyService(new ConsoleLogger())) {
                service.Start(args.Skip(1));
                Console.ReadLine();
                service.Stop();
            }
            break;
        default:
            Console.WriteLine("Supported arguments:");
            Console.WriteLine(" /install      Install the service");
            Console.WriteLine(" /uninstall    Uninstall the service");
            Console.WriteLine(" /interactive  Run the service interactively (on the console)");
            break;
        }
    } else {
        ServiceBase.Run(new MyService());
    }
}

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

2 голосов
/ 22 июля 2011

Я лично для себя нашел самое простое решение - не менять код, добавив больше беспорядка и директив #if #else, а просто:

  1. Скомпилируйте ваши сервисные двоичные файлы в режиме DEBUG
  2. Укажите установленную службу на DEBUG Двоичные файлы
  3. Запустить сервис
  4. Используйте подключиться к процессу диалоговое окно VS для подключения к запущенному процессу connect to process dialog

  5. Наслаждайтесь.

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

Удачи.

0 голосов
/ 12 декабря 2013

Для отладки или тестирования службы без ее установки внесите изменения в Program.cs следующим образом.

static class Program
{
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
    { 
      new MyService() 
    };
        ServiceBase.Run(ServicesToRun);
    }
   }

Измените его на:

static class Program
{
static void Main()
{
    #if(!DEBUG)
       ServiceBase[] ServicesToRun;
       ServicesToRun = new ServiceBase[] 
   { 
        new MyService() 
   };
       ServiceBase.Run(ServicesToRun);
     #else
       MyService myServ = new MyService();
       myServ.Process();
       // here Process is my Service function
       // that will run when my service onstart is call
       // you need to call your own method or function name here instead of Process();
     #endif
    }
}
0 голосов
/ 22 июля 2011

Метод Debugger.Launch - это хороший способ, но я предпочитаю создать класс, который выполняет обработку и вызывает его из службы. Затем его также можно вызывать из приложения выигрышных форм. например:

class ProcessingManager
{

    public void Start()
    {
     //do processing
    }

    public void Stop()
    {
    //stop
    }
}

затем в вашем приложении service / win form просто создайте экземпляр класса обработки в качестве переменной-члена и вызовите метод при запуске и остановке. Его можно использовать в сервисе или в приложении для запуска форм с кнопкой «Пуск» и «Стоп», который я нахожу намного быстрее, чем каждый раз подключать отладчик, потому что вы можете настроить запуск приложения Windows по умолчанию и добавить любые точки останова в обработку. менеджер.

выписка из сервисного кода:

namespace Service
{
    public partial class Service : ServiceBase
    {
        #region Members

        private ProcessingManager m_ProcessingManager = null;

        #endregion Members

        #region Constructor

        /// <summary>
        /// Constructor
        /// </summary>
        public Service()
        {
            InitializeComponent();

            try
            {
                //Instantiate the processing manager
                m_ProcessingManager = new ProcessingManager();
            }
            catch (Exception ex)
            {
                ErrorHandler.LogError(ex);
            }
        }

        #endregion Constructor

        #region Events

        /// <summary>
        /// Starts the processing
        /// </summary>
        /// <param name="args">Parameters</param>
        protected override void OnStart(string[] args)
        {
            try
            {
                //Start the Processing
                m_ProcessingManager.Start();
            }
            catch (Exception ex)
            {
                ErrorHandler.LogError(ex);
            }
        }

        /// <summary>
        /// Service Stopped
        /// </summary>
        protected override void OnStop()
        {
            try
            {
                //Stop Processing
                m_ProcessingManager.Stop();
            }
            catch (Exception ex)
            {
                ErrorHandler.LogError(ex);
            }
        }

        #endregion Events
    }
}
0 голосов
/ 22 июля 2011

Один из способов, который я делал раньше, - это вставка Debugger.Break () в метод службы при запуске. Скомпилируйте и установите сервис. Когда он запускается, он ломается и открывает диалог отладки, оттуда вы сможете подключить и отладить.

0 голосов
/ 22 июля 2011

Что я всегда делаю, так это ставлю:

#if DEBUG 

 Thread.Sleep(20000) 

#endif

в OnStart. Это дает мне 20 секунд, чтобы присоединиться.

Быстро и просто, просто не забудьте обернуть его в #if DEBUG #endif:)

0 голосов
/ 22 июля 2011

Попробуйте следовать этому руководству

РЕДАКТИРОВАТЬ: Лично у меня есть консольное приложение в том же проекте, который выполняет всю работу. Затем я просто запускаю сервис Main консольного приложения. Это облегчает отладку, особенно при разработке.

...