Как стать автором
Обновить

Комментарии 13

Спасибо! Мне очень пригодится, а то я все по старинке:
Debugger.Launch();
и
if(Debugegr.Attached)
Debugger.Break();
Если задача состоит только в том чтоб отловить метод старт, то можно принудительно вызвать отладчик методом System.Diagnostics.Debugger.Break();
Тут главная идея — это отлаживать службу как обычное приложение.
Всегда пользовался следующим методом (и не надо изобретать консольное приложение):
В коде сервиса:
public void Start()
{
// Тут логика инициализации
}

protected override void OnStart(string[] args)
{
Start();
}

В коде Program (опущу обработку исключений):
static void Main(string[] args)
{
if (Environment.UserInteractive)
{
#if DEBUG
(new MySvc()).Start();
Thread.Sleep(Timeout.Infinite);
#else
MessageBox.Show("Приложение должно быть установлено в виде службы Windows и не может быть запущено интерактивно.");
#endif
}
else
{
ServiceBase.Run(new MySvc());
}
}


Минус один — OnStop() таким образом отладить сложнее, но тоже решается.
Интересный способ. Спасибо, возьму на заметку.
Способ достаточно старый и проверенный, но… На мой взгляд главная идея OnStart должна быть в передаче управления сборке с логикой, которая в свою очередь должна быть покрыта тестами. Кроме того, иногда необходимо протестировать с правами под которыми была установлена служба. Поэтому мой выбор System.Diagnostics.Debugger.Break(), а Environment.UserInteractive использую для автоматической установки сервиса.
Я обычно, если у меня есть вин служба, добавляю проект консольного приложения, которое по функциональной логике представляет собой точный аналог вин-службы. В общем случае в вин-службе вызывается только один метод при старте, скажем, DoSomething(). Таким образом, что мешает вызвать этот же метод из консольного приложения, и для тестирования и отладки использовать именно его.
Так как вообще сам по себе проект вин службы не должен содержать какой-либо логике, единственное, что он должен сделать — это загрузить и вызвать какой-то внешний компонент.
Некоторые вещи не получится дебажить таким образом.
К примеру функций, которые используют привилегии пользователя System.
Еще время запуска и остановки сервисов необходимо тестить в реальных условиях, ибо система может прибить сервис если он долго будет загружаться/выгружаться.
Да много еще ньюансов.
Конечно иметь возможность запускать сервис как консоль это очень полезно, но нужно уметь обходится и без этого.
Иногда спасает Sleep на старте сервиса, но иногда приходится подтягивать тяжелую артиллерию, а именно — ядерный отладчик.

делаю нечто похожее

if (args.Any(s => s.Equals("/console", StringComparison.InvariantCultureIgnoreCase)))
{
//запуск сервиса как консольное приложение
}
else if (args.Any(s => s.Equals("/i", StringComparison.InvariantCultureIgnoreCase)))
{
//инсталляция сервиса
}
else if (args.Any(s => s.Equals("/u", StringComparison.InvariantCultureIgnoreCase)))
{
//удаление сервиса
}
else if (args.Any(s => s.Equals("/help", StringComparison.InvariantCultureIgnoreCase)))
{
//список возможных команд
}
else
{
//запуск сервиса
}


преимущество, в том что приложение может использоваться как консольное, а так же как и сервис + привычная отладка
Действительно, зачем городить огород, а не использовать обычный «int 3», в сишарпах — Debugger.Break()?
Иногда нормально отладить сервис можно только при помощи ядерного отладчика (WinDBG).
К примеру надо отдалить запуск сервиса в автозагрузке, или наоборот его остановку в момент остановки системы…
Кому интересно, есть отличный проект Topshelf: topshelf-project.com/
Позволяет стартовать сервис как консольное приложение, так и в виде windows service, предоствляю удобный механизм установки и запуска. Плюс поддерживает горячую замену кода сервиса, а также работает с Mono.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации