この質問のソリューションを多数のマシンに「展開」しているときに、一部のシングル コア マシンでひどい結果が得られることに気付きました (たとえば、インテル アトムではソリューションが見事に失敗します)。
ここで起こっていることは次のとおりです。SetWinEventHook(...)
コンソールの変更に対するコールバックを取得するために呼び出します。コンテキスト外の通知のため、イベントの処理とコンソールでのさらなる変更との間に同期がありません。そのため、マルチコア マシンはうまく機能しますが (完全ではありません)、シングル コア マシンはこれを台無しにします。
これはmsdnによると同期する必要があるため、インコンテキスト通知をオンにしました。C# では、これは Infinite Improbability Drive を要求するようなものなので、C で単純な dll を作成しました。これは、汚い作業を行うことができ、c# から dll と通信できます。ここまでは順調ですね。
コールバックは、コンソールを所有するプロセスではなく、conhost.exe で発生します。コールバックでは、conhost.exe のコンテキストでコンソール出力バッファにアクセスする方法が見つからないため、これは問題を引き起こします。もっと正確に言えば、ハンドルを取得する方法が見つからないようです。利用可能なものは次のとおりです。コンソール ウィンドウへのハンドル、コンソール アプリケーションと conhost.exe の両方のプロセス ID、およびコンソール アプリケーションへのパイプ。
そして、これが私がソファーで試したことです:
- を使用する
GetStdHandle(...)
と、ハンドルが無効になります (conhost.exe のコンテキストでは意味があります)。 - を使用して
CreateFile("CONOUT$"...)
、ディト - パイプを使用してコンソール アプリケーションに出力バッファから読み取らせると、デッドロックが発生します。書き込み中の読み取りを防止するためのロック メカニズムを疑っていますが、それは理にかなっています。
- 出力バッファ ハンドルを複製し、パイプ経由で渡します。コンソールハンドルを外部プロセスに複製できないため、喜びはありません。
- conhost.exe プロセスを提供しているコンソール プロセスのコンソールにアタッチしてから、CreateFile を実行します。
AttachConsole(...)
わかりました、これは私のお気に入りのものでしたが、ブロック 3 と同様に機能しません。
誰かが次に何を試すかについて何か考えがありますか? 私の c/c++/winapi のスキルはせいぜい中級レベルなので、何かを見落としている可能性が非常に高いです。明らかな方法は、すべてを船外に投げ出して、出力バッファーをポーリングして変更を確認することですが、それは最後の手段と考えます。MS は、イン コンテキスト イベントまたはアウト オブ コンテキスト イベントのいずれかが実際に使用可能であることを確認するのに十分なほどスマートであったと想定しているため、何かが欠けているに違いありません。