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
답변
이것을 시도 할 수도 있습니다.
- Windows 서비스를 만들고 설치하고 시작합니다…. 즉, Windows 서비스가 시스템에서 실행되고 있어야합니다.
- 서비스가 실행되는 동안 디버그 메뉴 로 이동하여 프로세스 연결 (또는 이전 Visual Studio의 프로세스)을 클릭 합니다.
- 실행중인 서비스를 찾은 다음 모든 사용자의 프로세스 표시 및 모든 세션의 프로세스 표시 가 선택 되어 있는지 확인한 다음 선택합니다.
- 첨부 버튼을 클릭 합니다
- 클릭 OK
- 닫기 클릭
- 원하는 위치에 중단 점을 설정하고 실행을 기다립니다. 코드가 해당 지점에 도달 할 때마다 자동으로 디버그됩니다.
- onStart () 인 경우 중단 점을 도달 가능한 위치에 놓은 다음 서비스를 중지하고 다시 시작하십시오.
(많은 인터넷 검색 끝에 “Visual Studio에서 Windows 서비스를 디버그하는 방법”에서이를 발견했습니다.)
답변
서비스 프로젝트에서 작업을 수행 할 모든 코드를 별도의 프로젝트로 분리 한 다음 정상적으로 실행하고 디버그 할 수있는 테스트 애플리케이션을 만들어야합니다.
서비스 프로젝트는 서비스 부분을 구현하는 데 필요한 셸일뿐입니다.
답변
Lasse V. Karlsen이 제안한대로 또는 디버거가 연결될 때까지 대기하는 서비스 루프를 설정합니다. 가장 간단한 것은
while (!Debugger.IsAttached)
{
Thread.Sleep(1000);
}
... continue with code
이렇게하면 서비스를 시작할 수 있으며 Visual Studio 내에서 “Attach to Process …”를 선택하고 서비스에 연결하면 정상적인 배출이 재개됩니다.
답변
그 주어 ServiceBase.OnStart
가 protected
가시성을, 나는 디버깅을 달성하기 위해 반사 경로를 내려 갔다.
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 서비스의 응용 프로그램과 정확히 동일 합니다.