Как отладить метод .NET Windows Service OnStart?
У меня есть код, написанный на .NET, который работает только при установке в качестве службы Windows. Сбой не позволяет службе даже запускаться. Я не могу понять, как я могу войти в метод OnStart.
Как отлаживать приложения Windows Service Applications дает мучительную подсказку:
Присоединение к процессу обслуживания позволяет отлаживать большинство, но не весь код службы; например, поскольку служба уже запущена, вы не можете отлаживать код в методе OnStart службы таким образом или код в методе Main, который используется для загрузки службы. Один из способов обойти это - создать временную вторую службу в своем сервисном приложении, которая существует только для помощи в отладке. Вы можете установить обе службы и запустить этот сервис "dummy" для загрузки процесса обслуживания. После того, как временная служба запустила этот процесс, вы можете использовать меню Debug в Visual Studio для присоединения к процессу службы.
Однако я не понимаю, как именно вы должны создать фиктивную службу для загрузки процесса обслуживания.
Ответы
Ответ 1
Одна вещь, которую вы могли бы сделать как временное обходное решение, - запустить отладчик в качестве первой строки кода в OnStart
System.Diagnostics.Debugger.Launch()
Это предложит вам отладчик, который вы хотите использовать. Просто установите решение уже в Visual Studio и выберите этот экземпляр из списка.
Ответ 2
Я обычно добавляю такой метод:
[Conditional("DEBUG")]
private void AttachDebugger()
{
Debugger.Break();
}
он будет вызван только для создания проектов Debug вашего проекта, и он приостановит выполнение и позволит вам прикрепить отладчик.
Ответ 3
После того, как у вас есть служба, установленная с помощью installutil.exe
, вы можете изменить Start Parameters
, чтобы перейти в отладчик, если служба запущена:
![enter image description here]()
Когда вы вручную запускаете сервис с параметром -debugWithVisualStudio
(или просто -d
), он автоматически обнаруживает правильный проект и запускает интерактивный отладчик в Visual Studio:
![enter image description here]()
Чтобы поддерживать эту функциональность, измените функцию службы OnStart()
:
/// <summary>
/// Executed when the service is started.
/// </summary>
/// <param name="args">Command line arguments.</param>
protected override void OnStart(string[] args)
{
try
{
//How to debug when running a Windows Service:
// 1. Right click on the service name in Windows Service Manager.
// 2. Select "Properties".
// 3. In "Start Parameters", enter "-d" (or "-debugWithVisualStudio").
// 4. Now, when you start the service, it will fire up Visual Studio 2012 and break on the line below.
// 5. Make sure you have UAC (User Access Control) turned off, and have Administrator privileges.
#if DEBUG
if (((ICollection<string>)args).Contains("-d")
|| ((ICollection<string>)args).Contains("-debugWithVisualStudio"))
{
Debugger.Launch(); // Launches VS2012 debugger.
}
#endif
ShellStart(args);
base.OnStart(args);
}
catch (Exception ex)
{
// Log exception here.
}
}
(необязательно) Если вы хотите сузить до точной строки кода, где служба вызывает ошибку, включите исключения из меню Visual Studio DEBUG .. Exceptions
. Когда вы продолжите отладку, она сломается на точной строке, которая бросает исключение.
![enter image description here]()
Ответ 4
Все работает отлично!
protected override void OnStart(string[] args)
{
System.Diagnostics.Debugger.Launch();
}
Ответ 5
Параметры, описанные выше, не работают в Windows 8.
Я добавил Thread.Sleep(15000); в мой метод OnStart() и установите точку останова на следующей строке кода. Это дает мне 15 секунд, чтобы приложить отладчик VS к моему процессу после запуска службы и позволил мне хорошо отладить метод OnStart().
Ответ 6
Вы можете добавить строку кода следующим образом:
System.Diagnostics.Debugger.Break()
в котором появится окно с предложением выбрать, какой отладчик использовать для отладки, например. позволяя вам подключаться к Visual Studio и входить в код.
см
http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.break.aspx
Ответ 7
Можно создать сопутствующий проект Службе Windows, который запускается как консольное приложение, но получает доступ к методам службы с использованием Reflection. См. Здесь подробности и пример: http://ryan.kohn.ca/articles/how-to-debug-a-windows-service-in-csharp-using-reflection/.
Ответ 8
Я знаю, что это поздно, но мы так же обрабатываем отладки служб Windows
Сначала создайте класс, который будет действовать как служба.
Добавьте соответствующие методы для запуска, остановки, паузы и т.д.
Добавить форму окна в проект службы.
В служебном коде создайте класс обслуживания, созданный выше, и выполните вызовы, необходимые для запуска и остановки службы в классе ServiceBase
Откройте Program.cs и добавьте следующие
#if DEBUG
[STAThread]
#endif
static void Main()
{
try
{
#if DEBUG
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new DebugForm());
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new YourWindowsService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
catch (Exception e)
{
logger.Error(DateTime.Now.ToString() + " - " + e.Source + " - " + e.ToString() + "\r\n------------------------------------\r\n");
}
}
При запуске в режиме DEBUG запустится форма окна. Просто не забудьте построить в режиме Release, когда закончите. Конечно, условная переменная компиляции может быть любой, что вам нравится. Вы даже можете создавать отдельные проекты, поэтому форма отладки - это собственный проект.
Надеюсь, что это поможет
Ответ 9
Вы также можете попробовать метод System.Diagnostics.Debugger.Launch(). Это помогает при отображении указателя отладчика в указанное место, и вы можете отлаживать код.
До этого шага установите ваш service.exe с помощью командной строки командной строки Visual Studio - installutil projectservice.exe
Затем запустите службу из панели управления → "Администрирование" → "Управление компьютером" → "Сервис и приложение" → "Службы" → "Имя вашей службы"
Ответ 10
Использовать следующий код в методе OnStart:
System.Diagnostics.Debugger.Launch();
Выберите вариант Visual Studio из всплывающего сообщения. Не забудьте запустить Visual Studio в качестве администратора.
Примечание. Чтобы использовать его только в режиме отладки, можно использовать директиву компилятора #if DEBUG, как показано ниже. Это предотвратит случайную или отладочную работу в режиме Release на сервере Production.
#if DEBUG
System.Diagnostics.Debugger.Launch();
#endif
Ответ 11
Как указывали другие, вам нужно добавить разрыв отладчика к OnStart-Method:
#if DEBUG
System.Diagnostics.Debugger.Break()
#endif
Также запустите VisualStudio в качестве администратора и разрешите, чтобы процесс мог автоматически отлаживаться другим пользователем (как объяснялось здесь):
reg add "HKCR\AppID\{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f
(Я также объяснил это здесь: fooobar.com/questions/24544/...)
Ответ 12
Попробуйте добавить Debugger.Break внутри проблемного метода. Когда служба запустит исключение, будет выбрано исключение, и вдовы должны предложить отладить его с помощью visual studio.
Ответ 13
Обычно у меня есть консольное приложение, которое претендует на роль SCM, например. вызывает "Начать", "Стоп", после чего я могу просто включить F5 в мои основные цели кодирования/отладки, а также использовать Debugger.Break для отладки, когда служба была установлена и запущена через SCM.
Это означает, что для начала нужно немного больше работы. У меня есть класс lib, который содержит весь служебный код, с классом, который предоставляет возможность запуска и остановки, чтобы оба класса службы Windows и консольное приложение могли звонить.
Matt
Ответ 14
Если вы добавите Debugger.Launch() в свой метод OnStart, и это не сработает, вы можете иметь ту же самую проблему, что и я, а именно, исключение произошло в конструкторе, поэтому OnStart никогда не вызывался. (головная пощелка)
(извините, если это был комментарий на чужой ответ, но у меня недостаточно комментариев для комментариев)
Ответ 15
Прежде чем идти в тему, советую. Всегда используйте журнал специально, если вы являетесь разработчиком на стороне сервера. Потому что есть некоторые определенные условия, которые вы не сможете произвести при отладке кода в visual studio.
Возвращаясь к теме, я использую флажок Envoirnment.UserInteractive, это действительно удобно увидеть в моем коде ниже
public static void Main(string[] args)
{
if (System.Environment.UserInteractive)
{
string parameter = string.Concat(args);
switch (parameter)
{
case "--install":
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
break;
case "--uninstall":
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
break;
default:
WindowsService service = new WindowsService();
service.OnStart(args);
Console.ReadKey();
service.OnStop();
break;
}
}
else
{
ServiceBase.Run(new WindowsService());
}
}
Из visual studio вы получите флаг UserInteractive, чтобы я запускал его как консольное приложение. Кроме того, вы можете запустить сборку продукта, дважды щелкнув ее и прикрепляя к нему отладчик, если хотите проверить его.
Ответ 16
У меня есть интересный способ сделать это. Я добавляю еще одну конфигурацию под названием DebugNoService
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugNoService|AnyCPU' ">
<OutputPath>.\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>DEBUG;TRACE;DEBUGNOSERVICE</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
Я использую директиву #if.
ProjectInstaller.cs
#if !DEBUGNOSERVICE
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;
.....
}
#endif
Я добавляю форму окна, и я также обертываю форму окна в
#if DEBUGNOSERVICE
...
static void Main()
{
Form form;
Application.EnableVisualStyles();
Application.DoEvents();
form = new <the name of the form>();
Application.Run(form);
}
...
#endif
в зависимости от выбранной конфигурации код запускается как приложение формы Windows, которое может быть легко отлажено или как служба.
Если вам кажется, что много работы, но она всегда работала и очень легко отлаживает код. Вы можете добавить в форму все виды вывода, чтобы вы могли наблюдать за их запуском.