我有一个控制台应用程序,需要在输出重定向(外部)到文件或管道(myapp.exe > Foo.bar)时禁用或启用某些操作。
如何检查我的Delphi控制台应用程序是否被重定向到文件或管道?
你可以使用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.
File_Type_Char
通常是一个 LPT 设备或控制台,因此这个方法可能无法告诉你程序的输出是否被重定向到打印机,例如:myapp.exe > LPT1
。 - Rob Kennedy..被重定向到文件或管道..
,所以他可以使用我回答中注释的代码:Result := (FileType=FILE_TYPE_PIPE) or (FileType=FILE_TYPE_DISK);
。 - RRUZmyexe > nul
将导致FILE_TYPE_CHAR
。因此,除非有人能想出更好的检测所有形式重定向的方法,否则我会保留我的答案在这里。 - David HeffernanGetFileType
的方法无法检测到所有形式的重定向,因为某些重定向是指向类型为 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.
GetConsoleMode
失败了怎么办? - kobikResult := not GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), Mode) and (GetLastError = ERROR_INVALID_HANDLE);
- kobik