Как устранить посторонний вывод консоли после Ctrl-C в Windows? - PullRequest
2 голосов
/ 28 марта 2019

При нажатии Ctrl-c почти всегда появляется дополнительный вывод.Я хотел бы убедиться, что после получения Ctrl-C программа не показывает ничего, кроме, возможно, «^ C».

Я обнаружил, что это в основном тот же вопрос, но это было для Linux и моегоПопытки «портировать» решение с Linux на Windows не увенчались успехом.

На данный момент я не могу попробовать и могу использовать некоторую помощь, которую я обязательно оценю.Спасибо.

Короткая программа, приведенная ниже, страдает от этой проблемы.

{$APPTYPE        CONSOLE}

program _SetConsoleCtrlHandler;

uses
  Windows,
  SysUtils
  ;

function CtrlHandler(CtrlType : DWORD) : BOOL; stdcall;
begin
  result := FALSE;

  case CtrlType of
    CTRL_C_EVENT,
    CTRL_BREAK_EVENT:
    begin
      result := TRUE;

      ExitProcess(7);
    end;
  end;
end;

var
  s : shortstring;

begin
  SetConsoleCtrlHandler(@CtrlHandler, TRUE);

  while TRUE do
  begin
    write('press <ctrl-c> to end this program : ');
    readln(s);
  end;
end.

1 Ответ

2 голосов
/ 28 марта 2019

Обычно я делаю так, чтобы у меня была отдельная единица, которая сигнализируется, и простое ожидание, как показано ниже. В основном проекте консоли вы вызываете WaitForCtrlC вместо Readln (). Вы также можете использовать TEvent и ждать события вместо цикла, как показано в этом примере:

uses
  {$IFDEF LINUX}
  Posix.Signal,
  {$ENDIF}
  {$IFDEF MSWINDOWS}
  Windows,
  {$ENDIF}
  SysUtils;

procedure WaitForCtrlC;

implementation

var
  Control_C: Boolean = False;

{$IFDEF MSWINDOWS}
function ConsoleCtrlHandler(dwCtrlType: DWORD): BOOL; stdcall;
begin
  if (dwCtrlType = CTRL_C_EVENT) then
    Control_C := True;
  Result := True;
end;
{$ENDIF}

{$IFDEF LINUX}
var
  sigIntHandler: sigaction_t;

procedure SigHandler(SigNum: Integer); cdecl;
begin
  Control_C := True;
end;
{$ENDIF}

procedure WaitForCtrlC;
begin
  while not Control_C do
    Sleep(25);
end;

initialization
  {$IFDEF MSWINDOWS}
  Windows.SetConsoleCtrlHandler(@ConsoleCtrlHandler, True);
  {$ENDIF}
  {$IFDEF LINUX}
  sigIntHandler._u.sa_handler := @SigHandler;
  sigemptyset(sigIntHandler.sa_mask);
  sigIntHandler.sa_flags := 0;
  sigaction(SIGINT, @sigIntHandler, nil);
  {$ENDIF}
...