Windowsでコンソールアプリケーションが勝手にキー入力待ち状態になる問題の解決方法

この記事は公開から4年以上経過しています。

Windowsのコンソールアプリケーションがいつの間にか止まってしまい、何かキーを押下すると処理が再開される問題の解決方法。

問題

コンソールアプリケーションを開始して処理の完了を待っているとき、ユーザーのキー入力が求められているわけでもないのにコンソール画面で何かキーを押下しないと処理が再開されない場合がある(ウィンドウタイトルが選択 xxxになる)。

原因

コマンドプロンプトの設定が「簡易編集モード」になっている状態でコンソール画面をクリックするなどコンソールテキストが選択状態になるとプログラムが停止される(Windowsの仕様?)。

解決方法

【既存ソフト等、プログラムを修正できない場合】

  • コマンドプロンプトの設定から、「簡易編集モード」の選択をオフにする。
    (アプリケーションの起動中、若しくはショートカットに設定すれば、そのアプリケーションのみに適用が可能)
    file

【開発ソフト等、プログラムを修正できる場合】

  • 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についても上記内容で解決できることを確認済。

以上です。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする