2016-08-31 3 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 (error) .Message;' – dbc

+0

@tayoung : 독립 실행 형이라 할지라도 저에게 좋습니다. 다른 방법으로 설명 할 수있는 경우 예제와 함께 질문을 게시하십시오. –

관련 문제