この記事は公開から4年以上経過しています。
Windowsのコンソールアプリケーションがいつの間にか止まってしまい、何かキーを押下すると処理が再開される問題の解決方法。
問題
コンソールアプリケーションを開始して処理の完了を待っているとき、ユーザーのキー入力が求められているわけでもないのにコンソール画面で何かキーを押下しないと処理が再開されない場合がある(ウィンドウタイトルが選択 xxx
になる)。
原因
コマンドプロンプトの設定が「簡易編集モード」になっている状態でコンソール画面をクリックするなどコンソールテキストが選択状態になるとプログラムが停止される(Windowsの仕様?)。
解決方法
【既存ソフト等、プログラムを修正できない場合】
- コマンドプロンプトの設定から、「簡易編集モード」の選択をオフにする。
(アプリケーションの起動中、若しくはショートカットに設定すれば、そのアプリケーションのみに適用が可能)
【開発ソフト等、プログラムを修正できる場合】
-
Win32APIでプログラム内で簡易編集モードフラグをリセットする。
サンプルソースコード(C#)
using System; using System.Runtime.InteropServices; namespace ConsoleFreezeTest210122 { internal class Program { private static void Main(string[] args) { // 簡易編集モードフラグをリセット var hConsole = Win32.GetStdHandle(Win32.STD_INPUT_HANDLE); uint mode; Win32.GetConsoleMode(hConsole, out mode); Win32.SetConsoleMode(hConsole, mode & ~Win32.ENABLE_QUICK_EDIT_MODE); // アプリケーションの処理(ダミーループ) int j = 0, k = 0; do { for (var i = 0; i < int.MaxValue; ++i) j = i; Console.WriteLine(k++); } while (true); } // Win32 API定義クラス private static class Win32 { public const int STD_INPUT_HANDLE = -10; public const uint ENABLE_QUICK_EDIT_MODE = 0x0040; [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); } } }
例はC#ですが、C++/VB.NETなどについてもおそらく同様です(未検証)。
2021.9.4追記:
VB.NETについても上記内容で解決できることを確認済。
以上です。