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

时间:2011-08-24 21:06:26

标签: delphi console-application

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

  1. 主控制台应用,将链接到BPL,
  2. 来自另一个“需要”第一个bpl的BPL,以及......
  3. 来自静态链接设备的DLL。
  4. 将构建BPL和DLL而不能查看{$ APPTYPE CONSOLE}指令,因此我无法使用IFDEF条件编译。 BPL和DLL需要能够以任何方式进行,具体取决于主应用程序是否是常规的winapp或控制台应用程序。

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

    if (UpperCase(ExtractFileName(ParamStr(0))) = 'MYCONSOLEAPP.EXE')  then ...
    

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

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

    更新:我发现我有点像this question,但我想调查德尔福人,看看是否有更好的方法。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:2)

使用构造函数注入在创建实例时注入记录器。 Here's a simple example.

您建议的测试应用程序是否为控制台应用程序的解决方案仅适用于这两种情况。构造函数注入解决方案几乎不再是代码,可以在任何需要输出的地方工作。