5

単純なウィンドウ サービスを作成していますが、デバッグすると、「ネイティブ フレームがコール スタックの一番上にあるため、式を評価できません。」というエラーが表示されます。また、Release でサービスをビルドして実行すると、ハングします。

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

        ServiceBase.Run(ServicesToRun);
    }

これが Program.cs ファイルのすべてで、通常は 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);
    }

Internal Void Run() は、Eren Ersönmez によるコメントの提案に基づいて最近追加されました。彼のアイデアは、残りを理解できるようになるまでロジックをデバッグするのに非常に役立ちました。

をネイティブ コール スタックに入れることができました。これは 76F17094 ret という 1 つの場所にあります。これが何なのかはわかりませんが、おそらく他の誰かがそうするでしょう。

また、サービスを開始して VS にアタッチしようとすると、2 つのインスタンスがあることに気付きます。1 つは通常の .exe で、もう 1 つは .vshost.exe です。他のサービスを開始すると、デバッガーの [プロセスにアタッチ] 部分に .exe ファイルしか表示されません。これは、1 つが v4 フレームワーク ( .vshost .exe サービス) にあり、もう 1 つが v2 (単一の .exe サービス) フレームワークにあるためでしょうか?

私はそれがうまくいったと信じています。使用していたタイマーに問題があったようです。私が使用していた元のタイマーは System.Windows.Forms タイマーでした。System.Timers.Timers に切り替えたところ、すべてが再び機能し始めました。まだ VS を接続できませんが、Internal Run() メソッドを使用してデバッグできます。助けてくれてありがとう

4

3 に答える 3

2

あなたの主な問題は、Windowsサービスexeを直接実行しようとしていることです。Windowsサービスは、サービスコントロールマネージャー(SCM)を介してのみ開始できます。VSでデバッグできるようにするには、次のようなものをお勧めします。

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

MyService1.Runサービスループを実行する新しいスレッドを生成するメソッドを作成します。Runまた、内から同じメソッドを呼び出しますMyService1.Onstart

このスキームは、SCMによって開始されるとサービスとして実行されますが、VSでデバッグされる場合(またはVSの外部でexeとして直接実行される場合)は通常のexeのように扱われます。

于 2012-06-01T14:22:22.540 に答える
2

問題

この通知は、スレッドが現在アンマネージ コードを実行しているため、式の評価には使用できないことを意味します。

状況によっては、式を評価する前に、呼び出しがマネージ コードに戻るのを待つことができます。残念ながら、この状況では、サービスをシャットダウンするまでそれは起こりません。

代替案

式を評価できるように、 ServiceBase.OnCustomCommandメソッドをオーバーライドし、そこにブレークポイントを配置することを検討してください。

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

次のようにカスタム コマンドを呼び出すことができます。

c:\>sc control YourServiceName 129
于 2012-06-01T14:07:15.987 に答える
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

于 2012-06-01T14:19:27.953 に答える