Search code examples
delphidelphi-xehybrid

how to create Delphi hybrid (console or GUI) application depending on a parameter?


Is it possible to create Create delphi application which is a GUI or Console application depending on a command or parameter(commands or parameter can be set while executing from command propt)

I have tried as flows but its look like console application even if I pass the parameter or not

if (ParamStr(1) = 'test') then
  begin
    {$APPTYPE CONSOLE}
    WriteLn('Program ConsoleTest is running.');
    WriteLn('Press the ENTER key to stop');
    ReadLn;
  end
  else
  begin
    Application.Initialize;
    Application.MainFormOnTaskbar := True;
    Application.CreateForm(TfrmMain, frmMain);
    Application.Run;
  end;

Solution

  • I am not sure if the IDE allows such code, but try:

    uses
      Vcl.Forms,
      Winapi.Windows;
    
    function GetConsoleWindow: HWnd; stdcall; 
      external 'kernel32.dll' name 'GetConsoleWindow';
    function AttachConsole(ProcessId: DWORD): BOOL; stdcall; 
      external 'kernel32.dll' name 'AttachConsole';
    
    const
      ATTACH_PARENT_PROCESS = DWORD(-1);
    
    begin
      if ParamStr(1) = 'test' then
      begin
        if not AttachConsole(ATTACH_PARENT_PROCESS) then
          AllocConsole;
        Writeln('Yay! This is a console');
      end
      else
      begin
        Application.Initialize;
        Application.MainFormOnTaskbar := True;
        Application.CreateForm(TForm42, Form42);
        Application.Run;
      end;
    end.
    

    Do not use {$APPTYPE CONSOLE} here.

    AttachConsole attaches to an existing (e.g. the parent) console.

    AllocConsole attaches a console to the current process. You can even run it alongside the GUI and Writeln/Write to it from your GUI code.

    Note that the process tries to attach to the parent console, if there is any. The program will write to that console, but it doesn't control it. So if someone (very likely the person that started the "GUI" program from the console) closes that parent console, the GUI program will close too (tried that several times).

    If you want to prevent that, always AllocConsole a new one and use that exclusively. You may however end up with two consoles, the parent one (if there was any) and the new one. Make your choice.