2016-08-31 18 views
1

ユーザーの操作なしでコードを実行するコンソールアプリケーションがあります。ユーザーが意図的にまたは偶然にコンソールウィンドウ内をクリックすると、すべての実行が停止します。ユーザーがコンソールウィンドウをクリックしたときにコードの実行が停止する

これは、コンソールウィンドウからのテキストのコピーと関係があります。アプリケーションが再度実行を開始する唯一の方法は、ユーザーがテキストを選択し、コンソールウィンドウを右クリックしてクリップボードにコピーする場合です。

これを実行するには、コンソールアプリケーションを作成し、次のコードを追加します。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var task = Task.Run(async() => 
     { 
      int i = 0; 
      while (true) 
      { 
       Console.WriteLine(i++); 
       await Task.Delay(1000); 
      } 
     }); 
     Console.ReadLine(); 
    } 
} 

コンソールウィンドウをクリックすると、タスクスレッドは実行を停止します。これはまったく望ましい動作ではなく、コンソールアプリケーションでこれが起こらないようにしたいのです。

どうすればこの問題を防ぐことができますか?私が見る限り、コンソールウィンドウ上のプロパティ/イベントは、この動作を制御することとは関係ありません。

ご覧のとおり、ウィンドウ内をクリックするとカーソルが表示されます。いずれかのキーを押すとカーソルが消えてアプリが動作し続ける Paused app

+0

「ワークスペースアプリ」とは何ですか?出力はどのように見えますか?コードを出力するコードはどのように見えますか? – Sinatr

+0

ワークスペースとは、コンソールウィンドウ、アプリ出力 - 「ファイルAをストレージBに移動...」のような処理操作のログを意味します。 –

+0

「医者、これを行うと痛いです! 「まあ、やってはいけない!」 –

答えて

5

これは、コンソールウィンドウでクイック編集モードが有効になっている場合に発生します。タイトルバーを右クリックして[プロパティ]を選択し、[オプション]タブを選択すると、クイック編集モードが有効になっているかどうかを確認できます。クイック編集モードを無効にすると、ウィンドウ内をクリックするとスクロールが停止しません。

スクロールが停止する理由は、ウィンドウ内でクリックされたマウスを使用してテキストを選択するためです。

プログラムのコンソールでクイック編集モードを無効にすることができますが、そうするにはGetConsoleModeSetConsoleMode API関数を呼び出す必要があります。ここでは、あなたがそれを行うだろう方法は次のとおりです。あなたはこのルートを下る場合

[DllImport("kernel32.dll", SetLastError=true)] 
public static extern IntPtr GetConsoleWindow(); 

[DllImport("kernel32.dll", SetLastError=true)] 
public static extern bool GetConsoleMode(
    IntPtr hConsoleHandle, 
    out int lpMode); 

[DllImport("kernel32.dll", SetLastError=true)] 
public static extern bool SetConsoleMode(
    IntPtr hConsoleHandle, 
    int ioMode); 

/// <summary> 
/// This flag enables the user to use the mouse to select and edit text. To enable 
/// this option, you must also set the ExtendedFlags flag. 
/// </summary> 
const int QuickEditMode = 64; 

// ExtendedFlags must be combined with 
// InsertMode and QuickEditMode when setting 
/// <summary> 
/// ExtendedFlags must be enabled in order to enable InsertMode or QuickEditMode. 
/// </summary> 
const int ExtendedFlags = 128; 

void DisableQuickEdit() 
{ 
    IntPtr conHandle = GetConsoleWindow(); 
    int mode; 

    if (!GetConsoleMode(conHandle, out mode)) 
    { 
     // error getting the console mode. Exit. 
     return; 
    } 

    mode = mode & ~(QuickEditMode | ExtendedFlags); 

    if (!SetConsoleMode(conHandle, mode)) 
    { 
     // error setting console mode. 
    } 
} 

void EnableQuickEdit() 
{ 
    IntPtr conHandle = GetConsoleWindow(); 
    int mode; 

    if (!GetConsoleMode(conHandle, out mode)) 
    { 
     // error getting the console mode. Exit. 
     return; 
    } 

    mode = mode | (QuickEditMode | ExtendedFlags); 

    if (!SetConsoleMode(conHandle, mode)) 
    { 
     // error setting console mode. 
    } 
} 

、それはあなたのプログラムの起動時に、元のコンソールモードの設定を保存し、ときにプログラムが終了、それを復元するために、おそらく良いアイデアです。だから、起動時に:

GetConsoleMode(GetConsoleWindow(), ref saveConsoleMode); 

と、あなたのプログラムが終了します。適切なエラー処理で

SetConsoleMode(GetConsoleWindow(), saveConsoleMode); 

を、もちろん。 GetConsoleModeの呼び出しに失敗した場合は、コンソールモードを復元したくないでしょう。

+0

これは、Visual Studioからデバッグを実行している場合のみ動作するようです。管理者として実行している場合でも、プログラムを単独で起動すると、問題が引き続き発生します。何か案は? – tayoung

+0

@tayoung - 各システムコールからのエラーの戻りをチェックし、エラーが発生した場合に 'Marshal.GetLastWin32Error()'を呼び出すようにしてください。例: 'var error = Marshal.GetLastWin32Error(); var errorMessage = new Win32Exception(エラー)。メッセージ; ' – dbc

+0

@tayoung:これはスタンドアロンで実行しているときでも動作します。他に例を示すことができる場合は、例を挙げて質問を投稿してください。 –

関連する問題