Как для отладки the.NET метод, служба Windows функции onStart?


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

как: отладка приложений-служб Windows дает дразнящий ключ:

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

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

16 51

16 ответов:

одна вещь, которую вы могли бы сделать в качестве временного обходного пути, - это запустить отладчик в качестве первой строки кода в OnStart

System.Diagnostics.Debugger.Launch()

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

Я склонен добавлять такой метод:

    [Conditional("DEBUG")]
    private void AttachDebugger()
    {
        Debugger.Break();
    }

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

если у вас есть служба, которая установлена с помощью 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

он работает просто отлично!

protected override void OnStart(string[] args)
{
    System.Diagnostics.Debugger.Launch();
}

приведенные выше параметры не работают в Windows 8.

Я добавил поток.Sleep (15000); в мой метод OnStart () и установите точку останова на следующей строке кода. Это дает мне 15 секунд, чтобы прикрепить VS debugger к моему процессу после запуска службы и позволило мне отладить метод OnStart() красиво.

вы можете добавить строку кода следующим образом:

System.Diagnostics.Debugger.Break()

который вызовет окно, предлагающее вам выбрать, какой отладчик использовать для отладки, например, позволяя вам прикрепить с помощью Visual Studio и войти в код.

посмотреть:

http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.break.aspx

можно настроить сопутствующий проект для службы Windows, которая работает как консольное приложение, но обращается к методам службы с помощью отражения. Смотрите здесь подробности и Пример: http://ryan.kohn.ca/articles/how-to-debug-a-windows-service-in-csharp-using-reflection/.

используйте следующий код в сервисе OnStart метод:

System.Diagnostics.Debugger.Launch();

выберите опцию Visual Studio из всплывающего сообщения. Не забудьте запустить Visual Studio от имени администратора.

Примечание: чтобы использовать его только в режиме отладки, #if DEBUG compiler директива может быть использована, как показано ниже. Это предотвратит случайную или отладку в режиме выпуска на рабочем сервере.

#if DEBUG
    System.Diagnostics.Debugger.Launch();
#endif

как указывали другие, вы должны добавить разрыв отладчика в метод OnStart:

#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

(Я также объяснил это здесь:https://stackoverflow.com/a/35715389/5132456)

Я знаю, что это поздно, но именно так мы обрабатываем отладку служб Windows

сначала создайте класс, который будет действовать как сервис.

добавьте соответствующие методы для запуска, остановки, приостановки и т. д...

добавить форму windows в проект службы.

в коде службы создайте класс службы, созданный выше, и выполните вызовы, необходимые для запуска и остановки службы в классе ServiceBase

Откройте программу.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");
        }
}

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

надеюсь, что это помогает

вы также можете попробовать

попробуйте добавить отладчик.Перерыв внутри проблемного метода. Когда служба запустится, будет выдано исключение, и вдовы должны предложить отладить его с помощью visual studio.

У меня обычно есть консольное приложение, которое притворяется SCM, например, запускает вызовы, останавливает которые я могу затем просто F5 в моих основных целях кодирования/отладки и использовать отладчик.Перерыв для отладки, когда служба была установлена и запущена через SCM.

Это означает немного больше работы для начала, у меня есть класс lib, который содержит весь код службы, с классом, который предоставляет Start и Stop, что класс службы Windows и консольное приложение могут как вызов.

матовая

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

(извините, если это должен был быть комментарий к чьему-то ответу, но у меня недостаточно кредитов, чтобы комментировать)

прежде чем я перейду в тему один советую. Всегда используйте журнал специально, если вы являетесь разработчиком на стороне сервера. Потому что есть некоторые определенные условия, которые вы не сможете создать при отладке кода в 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, поэтому я бы запустил его как консольное приложение, в дополнение к этому даже вы можете запустить сборку продукта, дважды щелкнув его и прикрепив к нему отладчик, если хотите его протестировать.

у меня есть интересный способ сделать это я добавляю еще одну конфигурацию под названием 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

добавить форму Windows и я также обернуть окна в форме

#if DEBUGNOSERVICE
...
static void Main() 
{
    Form     form;

    Application.EnableVisualStyles();
    Application.DoEvents();

    form = new <the name of the form>();

    Application.Run(form);
}
...
#endif

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

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