私は試していますが、これまでに見つけたものはすべて、GUIとフォームアプリを中心にしているようです。それは私が使っているものではありません。
最終的にはサービスになりますが、完了するまでは通常のアプリとして実行しています。誤って閉じてしまうと、別のサービスが最大30分間ハングし、データが不良になるという問題があります。 。リスナーを追加して、閉じているアプリをキャッチするのは簡単ですが。
しかし、私はそれを理解することができません。
私は試していますが、これまでに見つけたものはすべて、GUIとフォームアプリを中心にしているようです。それは私が使っているものではありません。
最終的にはサービスになりますが、完了するまでは通常のアプリとして実行しています。誤って閉じてしまうと、別のサービスが最大30分間ハングし、データが不良になるという問題があります。 。リスナーを追加して、閉じているアプリをキャッチするのは簡単ですが。
しかし、私はそれを理解することができません。
ここにあなたが必要とするもののための完璧な解決策があります:
このコードは、アプリケーションを閉じる可能性のあるすべてのイベントを検出します。
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
}
}
これを試して:
[編集]これは上記のリンクからの修正版です。
注:ユーザーが赤い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;
}
}
イベントをアプリ内で処理する場合は、
Windowsサービスの場合、
ServiceBase.OnStopを使用できます
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;
}
AppDomain.CurrentDomain.ProcessExit
イベント?