Подтвердить что ты не робот

Как отладить метод .NET Windows Service OnStart?

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

Как отлаживать приложения Windows Service Applications дает мучительную подсказку:

Присоединение к процессу обслуживания позволяет отлаживать большинство, но не весь код службы; например, поскольку служба уже запущена, вы не можете отлаживать код в методе OnStart службы таким образом или код в методе Main, который используется для загрузки службы. Один из способов обойти это - создать временную вторую службу в своем сервисном приложении, которая существует только для помощи в отладке. Вы можете установить обе службы и запустить этот сервис "dummy" для загрузки процесса обслуживания. После того, как временная служба запустила этот процесс, вы можете использовать меню Debug в Visual Studio для присоединения к процессу службы.

Однако я не понимаю, как именно вы должны создать фиктивную службу для загрузки процесса обслуживания.

4b9b3361

Ответ 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, которое может быть легко отлажено или как служба.

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