如何确定我是否作为控制台应用程序运行?(Win32上的Delphi)

Chr*_*ton 9 delphi console-application

我有一个通用单元,可以记录到GExperts Debugger和/或OutputDebugString.我将在控制台应用程序中使用它,所以我希望它能够通过输出到stdout writeln().
主可执行文件已经有{$ APPTYPE CONSOLE},但我不认为这对我有帮助.将从几个地方调用日志记录例程:

  1. 主控制台应用程序,将链接到BPL,
  2. 来自另一个"需要"第一个bpl的BPL,.....
  3. 从静态链接单元的DLL.

将构建BPL和DLL而不能查看{$ APPTYPE CONSOLE}指令,因此我不能使用IFDEF条件编译.BPL和DLL需要能够以任何方式进行,具体取决于主应用程序是否是常规的winapp或控制台应用程序.

我遇到的一个丑陋的解决方案是使用可执行文件的名称.例如:

if (UpperCase(ExtractFileName(ParamStr(0))) = 'MYCONSOLEAPP.EXE')  then ...
Run Code Online (Sandbox Code Playgroud)

但我讨厌这样做,因为我可以有其他控制台应用程序......

我宁愿只有一个神奇的函数AmIAConsoleApp:boolean; 有什么相似的吗?我在这个项目上使用Delphi2005.

更新:我看到我对这个问题有点重复,但我想调查德尔福人,看看是否有更好的方法.

Rob*_*edy 13

打电话GetStdHandle(Std_Output_Handle).如果成功并返回零,则没有可写入的控制台.其他返回值表示控制台已连接到进程,因此您可以向其写入(尽管控制台可能不是在控制台程序中记录消息的最理想位置,因为它们会干扰正常输出).像这样的东西:

function IAmAConsoleApp: Boolean;
var
  Stdout: THandle;
begin
  Stdout := GetStdHandle(Std_Output_Handle);
  Win32Check(Stdout <> Invalid_Handle_Value);
  Result := Stdout <> 0;
end;
Run Code Online (Sandbox Code Playgroud)

  • 这个答案还包括如果应用程序不是控制台类型但是分配了一个的情况.所以我认为这是正确的答案,即使问题是错误的(最终目的是输出到控制台,而不是找出可执行文件是如何链接的). (3认同)