質問

知っているために使用 setconsolehandler() したい場合は管理コンソール閉会イベント。

わからないのでどのようにブロックの CTRL_CLOSE_EVENT.たってはfalseを返して/trueで捕れるイベントが成功

ここには何かいいアントンGogolev!)

[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

public delegate bool HandlerRoutine(CtrlTypes CtrlType);

public enum CtrlTypes{
    CTRL_C_EVENT = 0,
    CTRL_BREAK_EVENT,
    CTRL_CLOSE_EVENT,
    CTRL_LOGOFF_EVENT = 5,
    CTRL_SHUTDOWN_EVENT
}

private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{ 
    if(ctrlType == CtrlTypes.CTRL_CLOSE_EVENT)
        return false;// I have tried true and false and viceversa with the return   
                     // true/false but I cant seem to get it right.
    return true;
}


//and then I use this to call it
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);

までの走行が可能と新しいスレッドがモニターの場合はコンソールは、ブロックがある場合のメインスレッドの中の何かをやって

役に立ちましたか?

解決

SetConsoleCtrlHandler() のためのドキュメントは言います:

  ユーザーは、コンソールを閉じてログオフ、またはプロセスが終了する前にクリーンアップする機会を持つようにシステムをシャットダウンすると、

システムはCTRL_CLOSE_EVENT、CTRL_LOGOFF_EVENT、およびCTRL_SHUTDOWN_EVENT信号を生成します。

これは、CTRL + CまたはCTRL + BREAKイベントを処理する場合とは異なり、あなたのプロセスは近く、ログオフ、またはシャットダウンをキャンセルする機会を得ていないことを意味します。

他のヒント

実際には、あなたは(私は、少なくともWindows XP上でこれを再現している)、それをブロックすることができます。あなたのハンドラ内で使用すると、睡眠とwhileループ無限を持っている場合たとえば、これは永遠に終了するから、このプロセスを停止します(長い時間のためか、少なくとも、またはユーザーがタスクマネージャを介してプロセスを強制終了するまで)。

あなたは本当にスレッドを開始するために必要な場合は、

、あなたは、待機状態(C#でAutoResetEvent)を使用することができますし、(新しいスレッドが、おそらくほとんどの場合は必要ありませんが)あなたのスレッドを起動し、あなたのスレッドがあるときに、待機状態を通知します仕上げ。しかし、ちょうどハンドラ内で任意のクリーンアップを行うと、ほとんどの場合で十分であろう。

最悪の場合、あなたは永遠に待つなかった場合は、

は、プロセスが実行中のままになりますと、あなたは(少なくともWindowsのXP上)に戻ってログインしたときにそれを見ることができます。 (それは、出口にあなたのapplicaitonを待ちながら)しかし、これは、デスクトップはログアウト画面に行く前に約20秒間停止させ、その後、(それが2回目のためにしようとしながら、私が思う)ログアウト画面で再び一時停止します。もちろん、私は強く永遠に待っに対して助言します。すべての長時間実行されているもののためにあなたは本当にサービスでこれを置く必要があります。

を発見できるhack'ることを回避することが、申請から閉会のない味を守コンソールにあります。特に、これに適したいと思い、GUIアプリケーションを生み出したコンソールとして'超'.らにMSDN書では、Ctrlハンドラと呼ばれる 新しいスレッド するプロセスで作成された呼び出しハンドラです。私の溶液に、その後、死の暴行に侵入前にスレッドのデフォルトのハンドラで呼ExitProcess.のハンドラは通常のコードにはC++のみ):

// Detach Console:
FreeConsole();
// Prevent closing:
ExitThread(0);
return TRUE; // Not reached

編集: でこれはな要因となりうることが課題として期待できるかもしれませんね。を呼び出AllocConsole()垂下が無限にな思い出のスレッドに早々に失敗したクリーンを一望できます。

編集2:

明らかにして直接的な課題を継続プログラムを実行する.さま、ありがとうございました意して強制的に終了されるスレッドはkernel32は、他の資源の中kernel32きが不確定である。この原因を予測不可能な問題が生じた時にプログラムを続けています。

主と思い、これらの問題に関するコンソールAPIとなります。のように、 AllocConsole に失敗したらこの時点以降であることを伝えてくださいハングアプリケーション)のプログラムが開けない新しいソフトである。している可能性が高いその他のコンソール機能が失敗します。基本的には何でもいいからその他の方と直接または間接的に)の呼び出しkernel32は未定義の動作が容疑者が実際にはありませんので問題以外のコンソール機能

私の結論はどうしたらよいかということです場合、このメソッドはできるが、早期終了が悪く、このと考えることができ、緊急ワーク周りの、控えめに使用され、まいます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top