Как определить, работаю ли я как консольное приложение? (Delphi на Win32) - PullRequest
9 голосов
/ 25 августа 2011

У меня есть общий модуль, который делает некоторые записи в GExperts Debugger и / или OutputDebugString. Я собираюсь использовать его в консольном приложении, поэтому я хочу, чтобы он мог выводить на стандартный вывод через 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 ...

Но я ненавижу это делать, поскольку у меня могут быть другие консольные приложения ...

Я бы предпочел просто использовать магическую функцию AmIAConsoleApp: boolean; Есть что-нибудь подобное? Я использую Delphi2005 в этом проекте.

Обновление: я вижу, что я вроде как дубликат этого вопроса , но я бы хотел опросить людей из Delphi, чтобы выяснить, есть ли лучший подход.

Ответы [ 2 ]

13 голосов
/ 25 августа 2011

Звоните 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;
2 голосов
/ 25 августа 2011

Использование инжектора конструктора для внедрения регистратора во время создания экземпляра. Вот простой пример.

Предлагаемое вами решение по проверке того, является ли приложение консольным, работает только для этих двух сценариев.Решение для внедрения в конструктор практически не содержит кода и работает там, где вам нужно.

...