2012-06-01 1 views
5

간단한 윈도우 서비스를 만들고 디버깅 할 때 "네이티브 프레임이 호출의 최상위에 있기 때문에 표현식을 평가할 수 없습니다 스택.". 또한 Release에서 서비스를 빌드하고 실행하면 멈 춥니 다. 모든 그것이 일반적으로 ServiceBase.Run (ServicesToRun) 라인에 걸려 가져옵니다 Program.cs 파일에네이티브 프레임이 호출 스택 맨 위에 있기 때문에 표현식을 계산할 수 없습니다.

static void Main() 
    { 
     ServiceBase[] ServicesToRun; 
     ServicesToRun = new ServiceBase[] { new MyService1() }; 

     ServiceBase.Run(ServicesToRun); 
    } 

이잖아.

내가 찾을 수 있었던 모든 것은 코드가 최적화되었거나 asp.net 및 response.redirect를 처리해야하기 때문에 평가되지 않은 표현식과 관련이 있습니다.

서비스 코드.

public TruckRateClearService() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     tmrProcess.Enabled = true; 
    } 

    protected override void OnCustomCommand(int command) 
    { 
     base.OnCustomCommand(command); 
     if (command == 129) 
     { 
      OnStart(null); 
     } 
    } 

    protected override void OnStop() 
    { 
     tmrProcess.Enabled = false; 
    } 

    private void tmrProcess_Tick(object sender, EventArgs e) 
    { 
     tmrProcess.Enabled = false; 

     try 
     { 
      eventLog.WriteEntry("Clearing Truck Rates Start" + DateTime.Now.ToString()); 

      TruckRateClearingAgent.Process(); 

      eventLog.WriteEntry("Clearing Truck Rates Finished" + DateTime.Now.ToString()); 
     } 
     catch (Exception ex) 
     { 
      eventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error); 
     } 

     tmrProcess.Enabled = true; 
    } 

    internal void Run() 
    { 
     tmrProcess_Tick(tmrProcess, null); 
    } 

내부 무효 실행() 에렌 Ersönmez에 의한 의견의 제안에 단지 최근에 추가되었습니다. 그의 아이디어는 나머지를 파악할 수있을 때까지 내 논리를 디버그하는 데 매우 도움이되었습니다.

나는 네이티브 호출 스택에 들어갈 수 있었고 한 위치, 76F17094 ret에 앉아있었습니다. 이제는이게 뭔지는 모르겠지만 어쩌면 다른 사람이 알게 될 것입니다.

또한 서비스를 시작하고 VS에 첨부 할 때 두 인스턴스가 있음을 알게됩니다. 하나는 정상적인 .exe이고 다른 하나는 .vshost.exe입니다. 다른 서비스를 시작하면 디버거의 Attach to process 부분에서 .exe 파일 만 볼 수 있습니다. 하나는 v4 Framework (.vshost .exe 서비스)에 있고 다른 하나는 v2 (단일 .exe 서비스) Framework에 있기 때문일 수 있습니까?

나는 그것이 효과가 있다고 생각한다. 문제는 내가 사용하고 있던 타이머로 거짓말 한 것 같습니다. 원래 사용하던 타이머는 System.Windows.Forms 타이머였습니다. System.Timers.Timers로 바꿨고 모든 것이 다시 작동하기 시작했습니다. 여전히 VS를 첨부 할 수는 없지만 내부 Run() 메소드를 사용하여 디버깅 할 수 있습니다.

답변

2

문제

이 알림 N, N- 모든 도움을 주셔서 감사합니다 스레드가 현재 관리되지 않는 코드를 실행되기 때문에 식을 평가하는 데 사용할 수 없습니다.

식을 평가하기 전에 호출이 관리되는 코드로 돌아갈 때까지 기다리는 경우가 있습니다. 불행히도이 상황에서는 서비스를 종료 할 때까지는 발생하지 않습니다.

대안

당신은 ServiceBase.OnCustomCommand 메서드를 재정의하고 표현식을 평가할 수 있도록이 중단 점을 넣어 고려할 수 있습니다. 다음과 같이

protected override void OnCustomCommand(int command) 
{ 
    //Debugger.Break() <- or just put a breakpoint in here. 
} 

당신은 사용자 정의 명령을 호출 할 수 있습니다

c:\>sc control YourServiceName 129 
+0

모든 것을 넣고 명령을 실행하면 효과가있었습니다. 그러나 내가 기능을 빠져 ​​나왔을 때 더 이상 진전시키지 못했습니다. 그리고 Debug-> Break All에 갔을 때, 서비스가 실패한 동일한 지점에있었습니다. 나는 내가 여기서 잘못된 것을하고 있다고 생각한다. –

+0

어떤 종류의 오류가 발생하고 있습니까? 정지 또는 예외? –

+0

"표현식을 평가할 수 없습니다 ..."전에 얻은 것과 동일합니다. 서비스가 ServiceBase.Run (ServicesToRun) 부분에만 멈추었습니까? –

0

당신이 관리되지 않는 코드가 예외를 던지고 수단을보고있는 예외를, 그래서 .NET 디버거는 당신에게 평소 표시 할 수 없습니다 유용한 세부 정보.

MyService1()에서 무엇을하고 있습니까? 코드를 게시 할 수 있습니까?

또한 환경에서 시작하여 서비스를 디버그하려고합니다. 그것은 작동하지 않을 수도 있습니다.

static void Main(params string[] args) 
{ 
    if (args.Length > 0 && args[0] == "/console") 
    { 
     // Run whatever your service calls here 
    } 
    else 
    { 
     ServiceBase[] ServicesToRun; 
     ServicesToRun = new ServiceBase[] { new MyService1() }; 

     ServiceBase.Run(ServicesToRun); 
    } 
} 

그런 다음 디버그 탭에서 프로젝트 속성에 명령 행 인수로 /console를 입력 :

나는 보통이 같은 물품. 응용 프로그램을 사용하여 디버깅 할 수 있어야합니다. 서비스를 먼저 설치하여 디버그 할 수 있습니다. http://msdn.microsoft.com/en-us/library/7a50syb3(v=vs.80).aspx

+0

원래 서비스를 다시 설치하고 VS를 연결했습니다. 나는 Eren의 충고를 보았고 그것을 나의 코드에 추가했다. 그래서 나는 정상적인 디버거를 사용할 수 있었다. 그러나 아직 관리되지 않는 코드를 찾지 못했습니다. 프로젝트의 속성에 들어가서 "안전하지 않은 코드 허용"을 켜는 것이 안전할까요? –

+0

다음 지침을 따르십시오. http://msdn.microsoft.com/en-us/library/tdw0c6sf(v=vs.80).aspx – greg84

2

주요 문제는 Windows 서비스 exe를 직접 실행하려고한다는 것입니다. Windows 서비스는 SCM (Service Control Manager)을 통해서만 시작할 수 있습니다. VS에서 디버깅 할 수 있도록하기 위해, 나는 이런 식으로 뭔가를 권하고 싶습니다 :

static void Main() 
{ 
    if (Environment.UserInteractive) 
    { 
     new MyService1().Run(); 
     Thread.Sleep(Timeout.Infinite); 
    } 
    else 
    { 
     ServiceBase.Run(new ServiceBase[] { new MyService1() }); 
    } 
} 

당신은 서비스 루프를 실행하는 새 스레드를 생성합니다 MyService1.Run 방법을 만들 것입니다. 또한 MyService1.Onstart에서 동일한 Run 메서드를 호출 할 수도 있습니다.

이 체계는 SCM에 의해 시작될 때 서비스로 실행되지만 VS에서 디버깅 될 때 (또는 VS 외부의 exe로 직접 실행될 때) 정상적인 exe처럼 처리합니다.

관련 문제