2012-06-01 5 views
5

Ich erstelle einen einfachen Fensterdienst, und wenn ich zum Debugging gehe, bekomme ich den Fehler: "Ausdruck kann nicht ausgewertet werden, da ein nativer Rahmen über dem Aufruf steht Stapel.". Außerdem, wenn ich den Dienst in Release erstellen und ausführen, hängt es einfach.Ausdruck kann nicht ausgewertet werden, da ein nativer Rahmen über dem Aufrufstack liegt

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

     ServiceBase.Run(ServicesToRun); 
    } 

Das ist alles, was in der Datei Program.cs ist, wo es wird normalerweise auf der ServiceBase.Run (ServicesToRun) Linie aufgehängt.

Alles, was ich finden konnte, bezieht sich nur auf den Ausdruck, der nicht ausgewertet wird, weil der Code optimiert ist oder mit asp.net und response.redirect umgehen muss.

Code für den Service.

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); 
    } 

Der Internal Void Run() wurde gerade kürzlich auf den Vorschlag in den Kommentaren von Eren Ersönmez hinzugefügt. Seine Idee war sehr hilfreich beim Debuggen meiner Logik, bis ich den Rest herausfinden konnte.

Ich war in der Lage, die in den nativen Call-Stack zu bekommen und es sitzt an einem Ort, 76F17094 ret. Jetzt habe ich keine Ahnung, was das ist, aber vielleicht jemand anderes.

Auch, wenn ich den Dienst starten und schauen, wenn ich ihn an VS anhefte, bemerke ich zwei Instanzen davon. Eine ist die normale .exe und eine andere ist eine .vshost.exe. Wenn ich andere Dienste starte, sehe ich nur die .exe-Datei im Attach-to-Process-Teil des Debuggers. Könnte dies sein, weil einer auf dem v4-Framework (.vshost.exe-Dienst) und ein anderer auf dem v2-Framework (einzelner .exe-Dienst) ist?

Ich glaube, ich habe es funktioniert. Es scheint, dass das Problem mit dem Timer gelogen hat, den ich benutzte. Der ursprüngliche Timer, den ich verwendete, war ein System.Windows.Forms-Timer. Ich habe es auf System.Timers.Timers umgestellt und alles hat wieder angefangen zu arbeiten. Trotzdem kann ich VS nicht anhängen, aber ich kann es immer noch mit der internen Run() Methode debuggen. Vielen Dank für all die Hilfe n.n

Antwort

2

Das Problem

Diese Meldung bedeutet, dass der Thread derzeit nicht verwalteten Code ausgeführt wird, und kann daher nicht verwendet werden, um den Ausdruck auszuwerten.

In einigen Situationen können Sie warten, bis der Aufruf zum verwalteten Code zurückkehrt, bevor Sie den Ausdruck auswerten. Leider wird dies in dieser Situation nicht passieren, bis Sie den Dienst herunterfahren.

Eine Alternative

Sie betrachten könnte die ServiceBase.OnCustomCommand Methode überschrieben und einen Haltepunkt setzen dort, so dass Sie Ihren Ausdruck auswerten kann.

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

Sie können den benutzerdefinierten Befehl aufrufen wie folgt:

c:\>sc control YourServiceName 129 
+0

Ich legte alles und führte den Befehl und es hat funktioniert. Als ich jedoch aus der Funktion heraustrat, würde ich mich nicht weiter bewegen. Und als ich zu Debug -> Break All ging, war es an dem Punkt, an dem der Service versagte. Ich denke, ich mache hier etwas falsch. –

+0

Welche Art von Fehler sehen Sie? Ein Hang oder eine Ausnahme? –

+0

Das selbe wie ich es zuvor bekommen habe "Ausdruck kann nicht ausgewertet werden ...". Würde der Dienst nur am ServiceBase.Run-Teil (ServicesToRun) hängen bleiben? –

0

Die Ausnahme, die Sie Mittel sind zu sehen, dass nicht verwalteten Code eine Ausnahme wirft, so dass die .NET-Debugger kann man nicht zeigen die üblichen nützliche Details.

Was machst du in MyService1()? Können Sie den Code darin posten?

Sie versuchen auch, den Dienst zu debuggen, indem Sie ihn nur aus der Umgebung starten. Das könnte nicht funktionieren.

Ich schreibe in der Regel etwas wie folgt aus:

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); 
    } 
} 

Dann in den Projekteigenschaften unter der Registerkarte Debuggen /console als Argumente Befehlszeile eingeben. Sie sollten in der Lage sein, in die Anwendung zu gelangen und sie zu debuggen. Sie können einen Dienst nur debuggen, indem Sie ihn zuerst installieren: http://msdn.microsoft.com/en-us/library/7a50syb3(v=vs.80).aspx

+0

Ich habe den Dienst ursprünglich neu installiert und VS an ihn angehängt. Ich schaue Erens Rat und fügte das meinem Code hinzu, so dass ich einfach den normalen Debugger verwenden konnte. Ich habe jedoch noch keinen unmanaged Code gefunden. Wäre es sicher, in die Eigenschaften für das Projekt zu wechseln und "Unsicheren Code zulassen" zu aktivieren? –

+0

Versuchen Sie die Anweisungen hier: http://msdn.microsoft.com/en-us/library/tdw0c6sf(v=vs.80).aspx – greg84

2

Ihr Hauptproblem ist, dass Sie versuchen, eine Windows-Dienst exe direkt auszuführen. Windows-Dienste können nur über den Service Control Manager (SCM) gestartet werden. Um in VS debuggen zu können, würde ich so etwas wie dies empfehlen:

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

Sie eine MyService1.Run Methode erstellen würde, die einen neuen Thread laicht, der die Serviceschleife läuft. Sie würden auch die gleiche Run Methode aus dem MyService1.Onstart aufrufen.

Dieses Schema führt es als Dienst aus, wenn es von SCM gestartet wird, behandelt es jedoch wie eine normale EXE, wenn es in VS debuggt wird (oder direkt als Exe außerhalb von VS ausgeführt wird).

Verwandte Themen