[c#] Visual Studio에서 Windows 서비스를 어떻게 디버깅합니까?

Visual Studio에서 Windows 서비스를 디버깅 할 수 있습니까?

나는 다음과 같은 코드를 사용했다.

System.Diagnostics.Debugger.Break();

하지만 다음과 같은 코드 오류가 발생합니다.

두 가지 이벤트 오류가 발생했습니다. eventID 4096 VsJITDebugger 및 “서비스가 시작 또는 제어 요청에 적시에 응답하지 않았습니다.”



답변

서비스 OnStart메소드 에서 다음 코드를 사용하십시오 .

System.Diagnostics.Debugger.Launch();

팝업 메시지에서 Visual Studio 옵션을 선택합니다.

참고 : 디버그 모드에서만 사용하려면 #if DEBUG다음과 같이 컴파일러 지시문을 사용할 수 있습니다. 이렇게하면 프로덕션 서버의 릴리스 모드에서 우발적이거나 디버깅이 방지됩니다.

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


답변

이것을 시도 할 수도 있습니다.

  1. Windows 서비스를 만들고 설치하고 시작합니다…. 즉, Windows 서비스가 시스템에서 실행되고 있어야합니다.
  2. 서비스가 실행되는 동안 디버그 메뉴 로 이동하여 프로세스 연결 (또는 이전 Visual Studio의 프로세스)을 클릭 합니다.
  3. 실행중인 서비스를 찾은 다음 모든 사용자의 프로세스 표시모든 세션의 프로세스 표시 가 선택 되어 있는지 확인한 다음 선택합니다.

여기에 이미지 설명 입력

  1. 첨부 버튼을 클릭 합니다
  2. 클릭 OK
  3. 닫기 클릭
  4. 원하는 위치에 중단 점을 설정하고 실행을 기다립니다. 코드가 해당 지점에 도달 할 때마다 자동으로 디버그됩니다.
  5. onStart () 인 경우 중단 점을 도달 가능한 위치에 놓은 다음 서비스를 중지하고 다시 시작하십시오.

(많은 인터넷 검색 끝에 “Visual Studio에서 Windows 서비스를 디버그하는 방법”에서이를 발견했습니다.)


답변

서비스 프로젝트에서 작업을 수행 할 모든 코드를 별도의 프로젝트로 분리 한 다음 정상적으로 실행하고 디버그 할 수있는 테스트 애플리케이션을 만들어야합니다.

서비스 프로젝트는 서비스 부분을 구현하는 데 필요한 셸일뿐입니다.


답변

Lasse V. Karlsen이 제안한대로 또는 디버거가 연결될 때까지 대기하는 서비스 루프를 설정합니다. 가장 간단한 것은

while (!Debugger.IsAttached)
{
    Thread.Sleep(1000);
}

... continue with code

이렇게하면 서비스를 시작할 수 있으며 Visual Studio 내에서 “Attach to Process …”를 선택하고 서비스에 연결하면 정상적인 배출이 재개됩니다.


답변

그 주어 ServiceBase.OnStartprotected가시성을, 나는 디버깅을 달성하기 위해 반사 경로를 내려 갔다.

private static void Main(string[] args)
{
    var serviceBases = new ServiceBase[] {new Service() /* ... */ };

#if DEBUG
    if (Environment.UserInteractive)
    {
        const BindingFlags bindingFlags =
            BindingFlags.Instance | BindingFlags.NonPublic;

        foreach (var serviceBase in serviceBases)
        {
            var serviceType = serviceBase.GetType();
            var methodInfo = serviceType.GetMethod("OnStart", bindingFlags);

            new Thread(service => methodInfo.Invoke(service, new object[] {args})).Start(serviceBase);
        }

        return;
    }
#endif

    ServiceBase.Run(serviceBases);
}

참고 Thread기본적 전경 스레드에 의해입니다. 가짜 서비스 스레드가 실행 return되는 Main동안 시작해도 프로세스가 종료되지 않습니다.


답변

Microsoft 문서에서는 여기 에서 Windows 서비스를 디버깅하는 방법 과 프로세스에 연결하여 디버깅하는 경우 놓칠 수있는 부분 을 설명합니다 .

아래는 내 작업 코드입니다. Microsoft에서 제안한 접근 방식을 따랐습니다.

이 코드를 program.cs다음에 추가하십시오 .

static void Main(string[] args)
{
    // 'If' block will execute when launched through Visual Studio
    if (Environment.UserInteractive)
    {
        ServiceMonitor serviceRequest = new ServiceMonitor();
        serviceRequest.TestOnStartAndOnStop(args);
    }
    else // This block will execute when code is compiled as a Windows application
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            new ServiceMonitor()
        };
        ServiceBase.Run(ServicesToRun);
    }
}

이 코드를 ServiceMonitor 클래스에 추가하십시오.

internal void TestOnStartAndOnStop(string[] args)
{
    this.OnStart(args);
    Console.ReadLine();
    this.OnStop();
}

이제 프로젝트 속성으로 이동하여 “응용 프로그램”탭을 선택하고 디버깅 할 때 출력 유형 을 “콘솔 응용 프로그램”으로 선택 하거나 디버깅이 완료되면 “Windows 응용 프로그램”을 선택하고 서비스를 다시 컴파일하고 설치합니다.

여기에 이미지 설명 입력


답변

콘솔 애플리케이션을 만들 수 있습니다. 이 main기능을 사용 합니다.

    static void Main(string[] args)
    {
        ImportFileService ws = new ImportFileService();
        ws.OnStart(args);
        while (true)
        {
            ConsoleKeyInfo key = System.Console.ReadKey();
            if (key.Key == ConsoleKey.Escape)
                break;
        }
        ws.OnStop();
    }

ImportFileService클래스는 상속 ( ServiceBase)을 제외하고 내 Windows 서비스의 응용 프로그램과 정확히 동일 합니다.