sourcecode

Windows 서비스를 쉽게 디버그할 수 있는 방법

copyscript 2023. 5. 4. 20:26
반응형

Windows 서비스를 쉽게 디버그할 수 있는 방법

Windows Service Control Manager를 통해 서비스를 시작한 다음 디버거를 스레드에 연결하는 것보다 코드를 단계적으로 수행하는 더 쉬운 방법이 있습니까?좀 번거롭고 좀 더 직접적인 방법이 있는지 궁금합니다.

서비스를 빠르게 디버그하려면 잠시 후에Debugger.Break().그 선에 도달하면 다시 VS로 돌아갑니다.작업이 끝나면 해당 줄을 제거하는 것을 잊지 마십시오.

업데이트: 에 대한 대안으로#if DEBUG프라그마스, 당신은 또한 사용할 수 있습니다.Conditional("DEBUG_SERVICE")기여하다.

[Conditional("DEBUG_SERVICE")]
private static void DebugMode()
{
    Debugger.Break();
}

의 신의에OnStart다음 메소드를 호출합니다.

public override void OnStart()
{
     DebugMode();
     /* ... do the rest */
}

여기서 코드는 디버그 빌드 중에만 활성화됩니다.서비스 디버깅을 위해 별도의 빌드 구성을 만드는 것이 유용할 수 있습니다.

또한 정상적인 실행과 서비스화를 위해 별도의 "버전"을 보유하는 것이 방법이라고 생각합니다. 그러나 이러한 목적을 위해 별도의 명령줄 스위치를 사용할 필요가 있습니까?

당신은 그냥 할 수 없나요:

public static int Main(string[] args)
{
  if (!Environment.UserInteractive)
  {
    // Startup as service.
  }
  else
  {
    // Startup as application
  }
}

그러면 더블 클릭(정말 필요한 경우 OK)을 통해 앱을 시작할 수 있고 Visual Studio에서 클릭(프로젝트 설정을 수정할 필요 없이)할 수 있는 "장점"이 있습니다./console옵션).

엄히말하면밀,면하,Environment.UserInteractive합니다.WSF_VISIBLE현재 창 측점에 플래그가 설정되어 있지만, 플래그가 반환되는 다른 이유가 있습니까?false(무중단) 서비스로 운영되는 것 외에?

몇 주 전에 새로운 서비스 프로젝트를 시작했을 때 이 게시물을 발견했습니다.많은 훌륭한 제안들이 있지만, 저는 여전히 제가 원하는 해결책을 찾지 못했습니다.를 ' 서스클호수출할있가는능성를스래비▁the가'능'로 부를 수 OnStart그리고.OnStop서비스 클래스를 수정하지 않는 메서드입니다.

해 낸 은 제가생낸해은책결해각▁the은▁i를 합니다.Environment.Interactive이 게시물에 대한 다른 답변에서 제안한 대로 실행 모드를 선택합니다.

static void Main()
{
    ServiceBase[] servicesToRun;
    servicesToRun = new ServiceBase[] 
    {
        new MyService()
    };
    if (Environment.UserInteractive)
    {
        RunInteractive(servicesToRun);
    }
    else
    {
        ServiceBase.Run(servicesToRun);
    }
}

RunInteractive된 도우는반사보여호호출를다합니자용하사를미를 합니다.OnStart그리고.OnStop메서드:

static void RunInteractive(ServiceBase[] servicesToRun)
{
    Console.WriteLine("Services running in interactive mode.");
    Console.WriteLine();

    MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart", 
        BindingFlags.Instance | BindingFlags.NonPublic);
    foreach (ServiceBase service in servicesToRun)
    {
        Console.Write("Starting {0}...", service.ServiceName);
        onStartMethod.Invoke(service, new object[] { new string[] { } });
        Console.Write("Started");
    }

    Console.WriteLine();
    Console.WriteLine();
    Console.WriteLine(
        "Press any key to stop the services and end the process...");
    Console.ReadKey();
    Console.WriteLine();

    MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop", 
        BindingFlags.Instance | BindingFlags.NonPublic);
    foreach (ServiceBase service in servicesToRun)
    {
        Console.Write("Stopping {0}...", service.ServiceName);
        onStopMethod.Invoke(service, null);
        Console.WriteLine("Stopped");
    }

    Console.WriteLine("All services stopped.");
    // Keep the console alive for a second to allow the user to see the message.
    Thread.Sleep(1000);
}

필요한 코드는 이것뿐이지만, 설명과 함께 워크스루도 작성했습니다.

서비스를 시작하는 동안 무슨 일이 일어나고 있는지 분석하는 것이 중요할 때가 있습니다.서비스를 시작하는 동안 디버거를 연결할 만큼 빠르지 않기 때문에 프로세스에 연결하는 것은 도움이 되지 않습니다.


즉, 다음 4줄의 코드를 사용하여 이 작업을 수행하고 있습니다.

#if DEBUG
    base.RequestAdditionalTime(600000); // 600*1000ms = 10 minutes timeout
    Debugger.Launch(); // launch and attach debugger
#endif

은 이은에삽다니에 됩니다.OnStart서비스의 방법은 다음과 같습니다.

protected override void OnStart(string[] args)
{
    #if DEBUG
       base.RequestAdditionalTime(600000); // 10 minutes timeout for startup
       Debugger.Launch(); // launch and attach debugger
    #endif
    MyInitOnstart(); // my individual initialization code for the service
    // allow the base class to perform any work it needs to do
    base.OnStart(args);
}

안 해보신 분들을 위해 아래에 자세한 힌트를 넣었습니다. 왜냐하면 쉽게 막힐 수 있기 때문입니다.다음 힌트는 Windows 7x64 Visual Studio 2010 Team Edition과 관련되어 있지만 다른 (새로운) 환경에서도 유효해야 합니다.


중요:서비스를 "수동" 모드로 배포합니다(다음 중 하나를 사용).InstallUtilVS 명령 프롬프트에서 유틸리티를 사용하거나 준비한 서비스 설치 관리자 프로젝트를 실행합니다.서비스를 시작하기 전에 Visual Studio를 열고 서비스의 소스 코드가 포함된 솔루션을 로드합니다. Visual Studio에서 필요에 따라 추가 중단점을 설정한 다음 서비스 제어판을 통해 서비스를 시작합니다.

에 에.Debugger.Launch"처리되지 않은 Microsoft"라는 대화상자가 나타납니다.Servicename.exe"에 NET Framework 예외가 발생하여 표시되었습니다.스크린샷에 표시된 대로 클릭합니다.
프레임워크 예외


그런 다음 윈도우즈 UAC에서 관리 자격 증명을 입력하라는 메시지가 표시될 수 있습니다.해당 항목을 입력하고 다음 작업을 계속합니다.

UAC 프롬프트

그런 다음 잘 알려진 Visual Studio Just-In-Time Debugger 창이 나타납니다.선택한 디버거를 사용하여 디버그할지 묻는 메시지가 나타납니다.를 클릭하기 전에 새 인스턴스를 열지 않음(두 번째 옵션)을 선택하십시오. 새 인스턴스는 소스 코드가 표시되지 않으므로 여기서는 유용하지 않습니다.따라서 이전에 연 Visual Studio 인스턴스를 대신 선택합니다.
VS 디버거 프롬프트

클릭한 잠시 후 Visual Studio는 다음 줄에 노란색 화살표를 표시합니다.Debugger.Launch 수 .MyInitOnStart여기에는 초기화가 포함됩니다. VS 디버거 중단점

를 누르면 준비한 다음 중단점에 도달할 때까지 즉시 실행이 계속됩니다.

힌트: 서비스를 계속 실행하려면 [디버깅] - > [모두 분리]를 선택합니다.이렇게 하면 서비스가 올바르게 시작되고 시작 코드 디버깅이 완료된 후 서비스와 통신하는 클라이언트를 실행할 수 있습니다.+(F5디버깅 중지)를 누르면 서비스가 종료됩니다.이 작업을 수행하는 대신 서비스 제어판을 사용하여 중지해야 합니다.



참고:

  • 릴리스를 빌드하면 디버그 코드가 자동으로 제거되고 서비스가 정상적으로 실행됩니다.

  • 디버거를 시작하고 연결하는 를 사용하고 있습니다.서비스를 시작할 때 연결된 디버거가 아직 없기 때문에 작동하지 않는 테스트도 수행했습니다("오류 1067: 프로세스가 예기치 않게 종료되었습니다.").

  • RequestAdditionalTime 서비스 시작 시간 제한을 더 길게 설정합니다(코드 자체를 지연시키는 것은 아니지만 즉시 계속됩니다).Debugger.Launch그렇지 서비스하기 위한 시간이 서비스를 시작할 때 호출하지할 수 .base.Onstart(args)디버거에서 충분히 빠르게.실질적으로 10분의 제한 시간을 설정하면 "서비스가 응답하지 않았습니다."라는 메시지가 표시되지 않습니다.디버거가 시작된 후 바로 표시됩니다.

  • 익숙해지면 이 방법은 기존 서비스 코드에 4줄을 추가하기만 하면 되기 때문에 매우 쉽습니다. 따라서 빠르게 제어 및 디버그를 수행할 수 있습니다.

제가 주로 하는 일은 서비스 논리를 별도의 클래스에 캡슐화하고 'runner' 클래스에서 시작하는 것입니다.이 러너 클래스는 실제 서비스이거나 콘솔 응용 프로그램일 수 있습니다.따라서 귀사의 솔루션에는 최소 3개의 프로젝트가 있습니다.

/ConsoleRunner
   /....
/ServiceRunner
   /....
/ApplicationLogic
   /....

Fabio Scopel의 YouTube 동영상은 Windows 서비스를 디버깅하는 방법을 매우 잘 설명합니다.실제 방법은 영상에서 4시 45분에 시작합니다...

여기 비디오에 설명된 코드가 있습니다...Program.cs 파일에 Debug 섹션의 내용을 추가합니다.

namespace YourNamespace
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
#if DEBUG
            Service1 myService = new Service1();
            myService.OnDebug();
            System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#else
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
                new Service1()
            };
            ServiceBase.Run(ServicesToRun);
#endif

        }
    }
}

Service1.cs 파일에 OnDebug() 메서드를 추가합니다.

    public Service1()
    {
        InitializeComponent();
    }

    public void OnDebug()
    {
        OnStart(null);
    }

    protected override void OnStart(string[] args)
    {
        // your code to do something
    }

    protected override void OnStop()
    {
    }

작동 방식

으로 기적으로생합니다야성해를 합니다.public void OnDebug()그것은 그것을 부릅니다.OnStart(string[] args)보호되고 있고 외부에서 접근할 수 없기 때문입니다.void Main()에 프그램추습니다었가가 되었습니다.#if 있는 입니다.#DEBUG.

는 Visual Studio를 합니다. »DEBUG프로젝트가 디버그 모드로 컴파일된 경우.때할 수 .

Service1 myService = new Service1();
myService.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);

이며, 할 수 .Release 정규 보통사들람들▁and▁regular▁the.else.

갱신하다

이 접근 방식이 가장 쉽습니다.

http://www.codeproject.com/KB/dotnet/DebugWinServices.aspx

저는 저의 원래 답변을 후세에 남깁니다.


서비스가 수행해야 할 작업이 있는지 정기적으로 확인하기를 원하기 때문에 제 서비스에는 타이머를 캡슐화하는 클래스가 있습니다.

서비스 시작 중에 클래스를 새로 만들고 StartEventLoop()을 호출합니다. (이 클래스는 콘솔 앱에서도 쉽게 사용할 수 있습니다.)

이 설계의 좋은 부작용은 타이머를 설정할 때 사용하는 인수를 사용하여 서비스가 실제로 작동하기 전에 지연을 발생시켜 디버거를 수동으로 연결할 수 있다는 것입니다.

p.s. 실행 중인 프로세스에 디버거를 수동으로 연결하는 방법...?

using System;
using System.Threading;
using System.Configuration;    

public class ServiceEventHandler
{
    Timer _timer;
    public ServiceEventHandler()
    {
        // get configuration etc.
        _timer = new Timer(
            new TimerCallback(EventTimerCallback)
            , null
            , Timeout.Infinite
            , Timeout.Infinite);
    }

    private void EventTimerCallback(object state)
    {
        // do something
    }

    public void StartEventLoop()
    {
        // wait a minute, then run every 30 minutes
        _timer.Change(TimeSpan.Parse("00:01:00"), TimeSpan.Parse("00:30:00");
    }
}

또한 저는 다음과 같은 작업을 하곤 했습니다(이전 답변에서 이미 언급했지만 릴리스 빌드에서 실행되지 않도록 하기 위해 조건부 컴파일러 [#if] 플래그를 사용했습니다).

때때로 클라이언트 데모에서 실행되는 앱에서 릴리스에서 빌드하는 것을 잊어버리고 디버거가 중단될 수 있기 때문에 이러한 방식을 중단했습니다.

#if DEBUG
if (!System.Diagnostics.Debugger.IsAttached)
{
    System.Diagnostics.Debugger.Break();
}
#endif

static void Main()
{
#if DEBUG
                // Run as interactive exe in debug mode to allow easy
                // debugging.

                var service = new MyService();
                service.OnStart(null);

                // Sleep the main thread indefinitely while the service code
                // runs in .OnStart

                Thread.Sleep(Timeout.Infinite);
#else
                // Run normally as service in release mode.

                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[]{ new MyService() };
                ServiceBase.Run(ServicesToRun);
#endif
}

명령 프롬프트(sc.exe)를 통해 서비스를 시작할 수도 있습니다.

개인적으로 디버깅 단계에서 코드를 독립 실행형 프로그램으로 실행하고 대부분의 버그가 해결되면 서비스로 실행으로 변경합니다.

제가 예전에 했던 일은 프로그램을 서비스나 일반 응용 프로그램으로 시작하는 명령줄 스위치였습니다.그런 다음 IDE에서 스위치를 설정하여 코드를 확인할 수 있도록 했습니다.

일부 언어에서는 IDE에서 실행 중인지 여부를 실제로 감지하고 이 전환을 자동으로 수행할 수 있습니다.

당신은 어떤 언어를 사용하고 있습니까?

TopShelf 라이브러리를 사용합니다.

콘솔 응용프로그램을 만든 다음 기본에서 설정을 구성합니다.

class Program
    {
        static void Main(string[] args)
        {
            HostFactory.Run(x =>
            {

                // setup service start and stop.
                x.Service<Controller>(s =>
                {
                    s.ConstructUsing(name => new Controller());
                    s.WhenStarted(controller => controller.Start());
                    s.WhenStopped(controller => controller.Stop());
                });

                // setup recovery here
                x.EnableServiceRecovery(rc =>
                {
                    rc.RestartService(delayInMinutes: 0);
                    rc.SetResetPeriod(days: 0);
                });

                x.RunAsLocalSystem();
            });
        }
}

public class Controller
    {
        public void Start()
        {

        }

        public void Stop()
        {

        }
    }

서비스를 디버깅하려면 비주얼 스튜디오에서 F5를 누르면 됩니다.

서비스를 설치하려면 cmd "console"을 입력합니다.exe 설치"

그런 다음 윈도우즈 서비스 관리자에서 서비스를 시작하고 중지할 수 있습니다.

사용하는 OS에 따라 다를 것 같은데, Vista는 세션 간 분리로 인해 서비스에 연결하기가 훨씬 어렵습니다.

제가 과거에 사용한 두 가지 옵션은 다음과 같습니다.

  • 프로세스에 대한 영구 디버거를 설정하려면 GFlags(Windows용 디버깅 도구)를 사용합니다.이것은 "이미지 파일 실행 옵션" 레지스트리 키에 있으며 매우 유용합니다."데스크톱과 상호 작용"을 활성화하려면 서비스 설정을 조정해야 할 것 같습니다.저는 이것을 서비스뿐만 아니라 모든 종류의 디버깅에 사용합니다.
  • 다른 옵션은 코드를 조금 분리하여 서비스 부분을 일반 앱 시작과 상호 교환할 수 있도록 하는 것입니다.이렇게 하면 간단한 명령줄 플래그를 사용하여 서비스가 아닌 프로세스로 시작할 수 있으므로 디버깅이 훨씬 쉬워집니다.

이게 도움이 되길 바랍니다.

저는 OnStart()의 초기화를 포함하여 서비스의 모든 측면을 디버깅하면서 SCM의 프레임워크 내에서 "콘솔" 또는 "앱" 모드 없이 전체 서비스 동작으로 실행할 수 있기를 원합니다.

같은 프로젝트에서 디버깅에 사용할 두 번째 서비스를 생성하여 이 작업을 수행합니다.디버그 서비스가 정상적으로 시작되면(즉, 서비스 MMC 플러그인에서) 서비스 호스트 프로세스가 생성됩니다.이렇게 하면 실제 서비스를 아직 시작하지 않았더라도 디버거를 에 연결하는 프로세스가 제공됩니다.프로세스에 디버거를 연결한 후 실제 서비스를 시작하면 OnStart()를 포함하여 서비스 라이프사이클의 모든 곳에서 디버거에 침입할 수 있습니다.

코드 침입을 최소화하기 때문에 디버그 서비스를 서비스 설정 프로젝트에 쉽게 포함할 수 있으며, 코드 한 줄을 주석 처리하고 프로젝트 설치 프로그램 하나를 삭제하여 프로덕션 릴리스에서 쉽게 제거할 수 있습니다.

세부사항:

이 구중이가때할을 구현하고 합니다.MyService또한생도 합니다.MyServiceDebug다 다에 추가니에 합니다.ServiceBase을 의열로 표시합니다.Program.cs 예:

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new MyService(),
            new MyServiceDebug()
        };
        ServiceBase.Run(ServicesToRun);
    }

서비스 프로젝트의 프로젝트 설치 관리자에 실제 서비스 및 디버그 서비스를 추가합니다.

여기에 이미지 설명 입력

서비스에 대한 설정 프로젝트에 서비스 프로젝트 출력을 추가할 때 실제 및 디버그 서비스가 모두 포함됩니다.설치 후 service.msc MMC 플러그인에 두 서비스가 모두 나타납니다.

MMC에서 디버그 서비스를 시작합니다.

Visual Studio에서 디버그 서비스가 시작한 프로세스에 디버거를 연결합니다.

실제 서비스를 시작하고 디버깅을 즐기십시오.

서비스를 작성할 때 모든 서비스 로직을 dll 프로젝트에 넣고 이 dll을 호출하는 두 개의 "호스트"를 만듭니다. 하나는 Windows 서비스이고 다른 하나는 명령줄 응용 프로그램입니다.

나는 디버깅을 위해 명령줄 응용 프로그램을 사용하고 명령줄 응용 프로그램에서 재현할 수 없는 버그에 대해서만 디버거를 실제 서비스에 연결합니다.

이 접근 방식을 사용하는 경우 실제 서비스에서 실행되는 동안 모든 코드를 테스트해야 하지만 명령줄 도구는 다른 환경이며 실제 서비스와 정확히 다르게 작동하지 않는 훌륭한 디버깅 보조 도구입니다.

Windows 서비스를 개발하고 디버깅할 때는 일반적으로 /console 시작 매개 변수를 추가하고 확인하여 콘솔 응용 프로그램으로 실행합니다.삶을 훨씬 편하게 해줍니다.

static void Main(string[] args) {
    if (Console.In != StreamReader.Null) {
        if (args.Length > 0 && args[0] == "/console") {
            // Start your service work.
        }
    }
}

디버거는 어때요?첫 번째 줄에서 브레이크()?

Windows 서비스를 디버그하기 위해 GFlags와 regedit으로 만든 .reg 파일을 결합합니다.

  1. exe-name 및 vsjit 디버거를 지정하여 GFlags 실행
  2. regedit을 실행하고 GFlags가 옵션을 설정하는 위치로 이동합니다.
  3. 파일 메뉴에서 "키 내보내기"를 선택합니다.
  4. .reg 확장자를 사용하여 파일을 저장합니다.
  5. 서비스를 디버그하고 싶을 때: .reg 파일을 두 번 클릭합니다.
  6. 디버깅을 중지하려면 두 번째 .reg 파일을 두 번 클릭합니다.

또는 다음 스니펫을 저장하고 서비스 이름을 바꿉니다.원하는 실행 파일 이름을 가진 exe.


debugon.reg:

Windows 레지스트리 편집기 버전 5.00
[HKEY_LOCAL_MACHINE\소프트웨어\Microsoft\]Windows NT\현재 버전\이미지 파일 실행 옵션\servicename입니다.exe] 을"GlobalFlag"="0x000000""Debugger"="vsjitdebugger.exe"

debugoff.reg:

Windows 레지스트리 편집기 버전 5.00
[HKEY_LOCAL_MACHINE\소프트웨어\Microsoft\]Windows NT\현재 버전\이미지 파일 실행 옵션\servicename입니다.exe] 을"GlobalFlag"="0x000000"

Windows 서비스 템플릿 C# 프로젝트를 사용하여 새 서비스 앱을 만듭니다. https://github.com/HarpyWar/windows-service-template

콘솔/서비스 모드가 자동으로 검색되고 서비스의 자동 설치/제거 및 가장 많이 사용되는 몇 가지 기능이 포함되어 있습니다.

다음은 추가적인 "디버그" 방법과 통합 VS 장치 테스트 없이 서비스를 테스트할 때 사용한 간단한 방법입니다.

[TestMethod]
public void TestMyService()
{
    MyService fs = new MyService();

    var OnStart = fs.GetType().BaseType.GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

    OnStart.Invoke(fs, new object[] { null });
}

// As an extension method
public static void Start(this ServiceBase service, List<string> parameters)
{
     string[] par = parameters == null ? null : parameters.ToArray();

     var OnStart = service.GetType().GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

     OnStart.Invoke(service, new object[] { par });
}

디버거 실행을 아무 곳에나 놓고 시작할 때 Visual studio를 연결하기만 하면 됩니다.

#if DEBUG
    Debugger.Launch();
#endif

또한 VS를 관리자로 시작해야 하며 프로세스를 다른 사용자가 자동으로 디버깅할 수 있도록 허용해야 합니다(아래 설명 참조).

reg add "HKCR\AppID{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f

일상적인 소규모 프로그래밍을 위해 서비스를 쉽게 디버그할 수 있는 아주 간단한 방법을 사용했습니다.

서비스를 시작할 때 명령줄 매개 변수 "/debug"를 확인합니다.이 매개 변수를 사용하여 서비스를 호출하는 경우 일반적인 서비스 시작은 수행하지 않고 모든 수신기를 시작하고 "디버그가 진행 중입니다. 종료하려면 ok를 누르십시오."라는 메시지 상자를 표시합니다.

따라서 서비스가 일반적인 방식으로 시작되면 서비스로 시작되고 명령줄 매개 변수/디버깅으로 시작되면 일반 프로그램처럼 작동합니다.

VS에서는 디버깅 매개 변수로 /debug를 추가하고 서비스 프로그램을 직접 시작합니다.

이렇게 하면 대부분의 작은 문제를 쉽게 디버그할 수 있습니다.물론 일부 항목은 여전히 서비스로 디버깅해야 하지만 99%의 경우 이 정도면 충분합니다.

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

저는 JOP의 답변에 변형을 사용합니다.명령줄 매개 변수를 사용하여 프로젝트 속성이 있는 IDE에서 또는 윈도우즈 서비스 관리자를 통해 디버깅 모드를 설정할 수 있습니다.

protected override void OnStart(string[] args)
{
  if (args.Contains<string>("DEBUG_SERVICE"))
  {
    Debugger.Break();
  }
  ...
}

기존 Windows 서비스 프로그램에서 문제를 해결하려면 '디버거'를 사용하십시오.다른 남자들이 제안한 대로 break()'.

새로운 윈도우 서비스 프로그램을 위해서, 저는 제임스 마이클 헤어의 방법을 사용하는 것을 제안합니다. http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable-windows-service-template-redux.aspx

static class Program
{
    static void Main()
    {
        #if DEBUG

        // TODO: Add code to start application here

        //    //If the mode is in debugging
        //    //create a new service instance
        Service1 myService = new Service1();

        //    //call the start method - this will start the Timer.
        myService.Start();

        //    //Set the Thread to sleep
        Thread.Sleep(300000);

        //    //Call the Stop method-this will stop the Timer.
        myService.Stop();

         #else
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new Service1() 
        };

        ServiceBase.Run(ServicesToRun);
         #endif
    }
}

붙여넣기

Debugger.Break();

당신이 코드하는 모든 곳.

예를들면,

internal static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    private static void Main()
    {
        Debugger.Break();
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            new Service1()
        };
        ServiceBase.Run(ServicesToRun);
    }
}

부딪칠 것입니다Debugger.Break();프로그램을 실행할 때 사용합니다.

디버깅에는 두 가지 옵션이 있습니다.

  1. 로그 파일 만들기 : 개인적으로 저는 애플리케이션 로그나 이벤트 로그를 사용하는 것보다 텍스트 파일과 같은 별도의 로그 파일을 선호합니다.그러나 정확한 오류 위치를 파악하기가 여전히 어렵기 때문에 시간을 대신하여 많은 비용이 소요됩니다.
  2. 응용프로그램을 콘솔 응용프로그램으로 변환합니다. 그러면 VS에서 사용할 수 있는 모든 디버깅 도구를 사용할 수 있습니다.

제가 주제를 위해 만든 이 블로그 게시물을 참조해 주세요.

가장 좋은 방법은 '시스템'을 사용하는 것입니다.진단의 네임스페이스입니다.

비주얼 스튜디오에서 디버그 모드와 릴리스 모드를 전환하려면 아래와 같이 디버그 모드와 릴리스 모드의 경우 블록에 코드를 동봉하십시오.

#if DEBUG  // for debug mode
       **Debugger.Launch();**  //debugger will hit here
       foreach (var job in JobFactory.GetJobs())
            {
                //do something 
            }

#else    // for release mode
      **Debugger.Launch();**  //debugger will hit here
     // write code here to do something in Release mode.

#endif

Microsoft - https://learn.microsoft.com/en-us/dotnet/framework/windows-services/how-to-debug-windows-service-applications#how-to-run-a-windows-service-as-a-console-application공식 문서에 따라 Windows 서비스를 쉽게 디버깅할 수 있었습니다.

윈도우 서비스를 디버깅을 위한 콘솔 앱으로 실행하라고 합니다.

언급URL : https://stackoverflow.com/questions/125964/easier-way-to-debug-a-windows-service

반응형