如何检查我的Delphi控制台应用程序是否重定向到文件或管道?

Sal*_*dor 10 windows delphi winapi redirect delphi-xe

我有一个控制台应用程序,当输出重定向(外部)到文件或管道时,必须禁用或启用某些操作(myapp.exe> Foo.bar)

如何检查我的Delphi控制台应用程序是否重定向到文件或管道?

RRU*_*RUZ 12

你可以使用GetStdHandleGetFileType功能.

首先使用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.
Run Code Online (Sandbox Code Playgroud)

  • 该文档提到`File_Type_Char`"通常是LPT设备或控制台",因此这种方法可能无法告诉您何时将程序的输出重定向到打印机:`myapp.exe> LPT1`. (3认同)
  • 确实,但是op专门要求`..重定向到文件或管道......所以他可以使用`Result:=(FileType = FILE_TYPE_PIPE)或(FileType = FILE_TYPE_DISK); `代码评论我的答案. (2认同)

Dav*_*nan 9

我在这里提出的方法感觉很难,但是我找不到更好的方法来检测标准输出是否已经从屏幕控制台重定向.使用的方法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.
Run Code Online (Sandbox Code Playgroud)

  • @kobik如果您无法访问自己的控制台,那么游戏就结束了! (2认同)
  • 我要问的是,如果这句话是一个事实:"如果GetConsoleMode()失败,那么你的控制台已被重定向". (2认同)
  • 我认为这应该更好:`结果:=不是GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),模式)和(GetLastError = ERROR_INVALID_HANDLE); (2认同)