4

私は試していますが、これまでに見つけたものはすべて、GUIとフォームアプリを中心にしているようです。それは私が使っているものではありません。

最終的にはサービスになりますが、完了するまでは通常のアプリとして実行しています。誤って閉じてしまうと、別のサービスが最大30分間ハングし、データが不良になるという問題があります。 。リスナーを追加して、閉じているアプリをキャッチするのは簡単ですが。

しかし、私はそれを理解することができません。

4

4 に答える 4

5

ここにあなたが必要とするもののための完璧な解決策があります:

C#でコンソールアプリケーションの終了を検出しています

このコードは、アプリケーションを閉じる可能性のあるすべてのイベントを検出します。

  • Control + C
  • コントロール+ブレイク
  • イベントを閉じる(閉じるボタンを使用した、プログラムの「通常の」終了)
  • ログオフイベント(ログオフを使用)
  • シャットダウンイベント(システム終了)
namespace Detect_Console_Application_Exit2
{
  class Program
  {
    private static bool isclosing = false;

    static void Main(string[] args)
    {
      SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
      Console.WriteLine("CTRL+C,CTRL+BREAK or suppress the application to exit");
      while (!isclosing) ;
    }

    private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
    {
      // Put your own handler here
      switch (ctrlType)
      {
        case CtrlTypes.CTRL_C_EVENT:
          isclosing = true;
          Console.WriteLine("CTRL+C received!");
          break;

        case CtrlTypes.CTRL_BREAK_EVENT:
          isclosing = true;
          Console.WriteLine("CTRL+BREAK received!");
          break;

        case CtrlTypes.CTRL_CLOSE_EVENT:
          isclosing = true;
          Console.WriteLine("Program being closed!");
          break;

        case CtrlTypes.CTRL_LOGOFF_EVENT:
        case CtrlTypes.CTRL_SHUTDOWN_EVENT:
          isclosing = true;
          Console.WriteLine("User is logging off!");
          break;
      }
      return true;
    }

    #region unmanaged

    // Declare the SetConsoleCtrlHandler function
    // as external and receiving a delegate.
    [DllImport("Kernel32")]
    public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

    // A delegate type to be used as the handler routine
    // for SetConsoleCtrlHandler.
    public delegate bool HandlerRoutine(CtrlTypes CtrlType);

    // An enumerated type for the control messages
    // sent to the handler routine.
    public enum CtrlTypes
    {
      CTRL_C_EVENT = 0,
      CTRL_BREAK_EVENT,
      CTRL_CLOSE_EVENT,
      CTRL_LOGOFF_EVENT = 5,
      CTRL_SHUTDOWN_EVENT
    }

    #endregion

    }
}
于 2012-05-16T15:12:56.127 に答える
2

これを試して:

[編集]これは上記のリンクからの修正版です。

注:ユーザーが赤いXをクリックしてコンソールウィンドウを閉じた場合、アプリが強制終了されるまでの応答時間は非常に限られています。次のプログラムを実行する場合は、メッセージボックスが表示されるまでの時間を確認してください。

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;


namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            SetConsoleCtrlHandler(ConsoleCtrlCheck, true);
            Console.WriteLine("CTRL+C,CTRL+BREAK or suppress the application to exit");

            while (!isclosing)
            {
                Thread.Sleep(1000);
            }
        }

        private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
        {
            // Put your own handling here:

            switch (ctrlType)
            {
                case CtrlTypes.CTRL_C_EVENT:

                    isclosing = true;

                    Console.WriteLine("CTRL+C received!");

                    break;

                case CtrlTypes.CTRL_BREAK_EVENT:

                    isclosing = true;

                    Console.WriteLine("CTRL+BREAK received!");

                    break;

                case CtrlTypes.CTRL_CLOSE_EVENT:

                    isclosing = true;

                    Console.WriteLine("Program being closed!");
                    MessageBox.Show("AHA!");

                    break;

                case CtrlTypes.CTRL_LOGOFF_EVENT:
                case CtrlTypes.CTRL_SHUTDOWN_EVENT:

                    isclosing = true;

                    Console.WriteLine("User is logging off!");

                    break;
            }

            return true;
        }

        #region unmanaged

        // Declare the SetConsoleCtrlHandler function as external and receiving a delegate.

        [DllImport("Kernel32")]

        public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

        // A delegate type to be used as the handler routine for SetConsoleCtrlHandler.

        public delegate bool HandlerRoutine(CtrlTypes CtrlType);

        // An enumerated type for the control messages sent to the handler routine.

        public enum CtrlTypes
        {

            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT,
            CTRL_CLOSE_EVENT,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT
        }

        #endregion

        private static bool isclosing;
    }
}
于 2012-05-16T15:16:08.747 に答える
1

イベントをアプリ内で処理する場合は、

  1. Windowsサービスの場合、

    ServiceBase.OnStopを使用できます

  2. WCFサービスの場合は ServiceHost.Closedイベントを使用できます。ServiceHostは、Communication HostからClosed(および関連イベント)を継承します

イベントを別のアプリで処理する場合は、Process.Exitedイベントを使用できます。

var serviceProcesses = Process.GetProcessesByName("service.exe");
if(serviceProcesses != null && serviceProcesses.Length>0)
{
    serviceProcesses[0].Exited += OnServiceClosed;
}
于 2012-05-16T15:18:34.203 に答える
0

AppDomain.CurrentDomain.ProcessExitイベント?

于 2012-05-16T15:15:02.113 に答える