Как проверить, перенаправлено ли приложение консоли Delphi в файл или канал?

У меня есть консольное приложение, которое должно отключать или активировать некоторые операции, когда вывод перенаправляется (внешне) в файл или канал (myapp.exe > ​​Foo.bar)

Как я могу проверить, перенаправлено ли консольное приложение Delphi на файл или канал?

Ответ 1

вы можете использовать функции GetStdHandle и GetFileType.

сначала вы извлекаете дескриптор вывода консоли с помощью функции GetStdHandle, а затем вы можете проверить тип дескриптора с помощью функции GetFileType.

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows,
  SysUtils;


function ConsoleRedirected: Boolean;
var
  FileType : DWORD;
begin
  FileType:= GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
  Result  := (FileType=FILE_TYPE_PIPE) or (FileType=FILE_TYPE_DISK);
end;


begin
  try
    if ConsoleRedirected then
      Writeln('Hello From File')
    else
      Writeln('Hello Console');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Ответ 2

Подход, который я здесь представляю, выглядит взломанным, но я не могу найти лучший способ определить, был ли стандартный вывод перенаправлен от экранной консоли. Подход с использованием GetFileType не может обнаружить все формы перенаправления, поскольку некоторые перенаправления относятся к устройствам типа FILE_TYPE_CHAR.


Вызовите GetConsoleMode(), передав стандартный дескриптор вывода. Если GetConsoleMode() не удалось, ваша консоль была перенаправлена.

program RedirectionDetection;
{$APPTYPE CONSOLE}
uses
  Windows;

function ConsoleRedirected: Boolean;
var
  Mode: DWORD;
begin
  Result := not GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), Mode);
end;

begin
  if ConsoleRedirected then begin
    Writeln('I have been redirected');
  end else begin
    Writeln('I am a console');
    Readln;
  end;
end.