This question is very similar (if not exactly the same) as something I was trying to accomplish.  I wanted to detect if my app was executed from a cmd.exe and send output to the parent console, otherwise it would display a gui.  The answers here helped me solve my issue.  Here is the code I came up with as an experiment:
ParentChecker.dpr
program ParentChecker;
uses
  Vcl.Forms,
  SysUtils,
  PsAPI,
  Windows,
  TLHelp32,
  Main in 'Main.pas' {frmParentChecker};
{$R *.res}
function AttachConsole(dwProcessID: Integer): Boolean; stdcall; external 'kernel32.dll';
function FreeConsole(): Boolean; stdcall; external 'kernel32.dll';
function GetParentProcessName(): String;
const
  BufferSize = 4096;
var
  HandleSnapShot: THandle;
  EntryParentProc: TProcessEntry32;
  CurrentProcessId: THandle;
  HandleParentProc: THandle;
  ParentProcessId: THandle;
  ParentProcessFound: Boolean;
  ParentProcPath: String;
begin
  ParentProcessFound:=False;
  HandleSnapShot:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  if HandleSnapShot<>INVALID_HANDLE_VALUE then
  begin
    EntryParentProc.dwSize:=SizeOf(EntryParentProc);
    if Process32First(HandleSnapShot,EntryParentProc) then
    begin
      CurrentProcessId:=GetCurrentProcessId();
      repeat
        if EntryParentProc.th32ProcessID=CurrentProcessId then
        begin
          ParentProcessId:=EntryParentProc.th32ParentProcessID;
          HandleParentProc:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,False,ParentProcessId);
          if HandleParentProc<>0 then
          begin
            ParentProcessFound:=True;
            SetLength(ParentProcPath,BufferSize);
            GetModuleFileNameEx(HandleParentProc,0,PChar(ParentProcPath),BufferSize);
            ParentProcPath:=PChar(ParentProcPath);
            CloseHandle(HandleParentProc);
          end;
          Break;
        end;
      until not Process32Next(HandleSnapShot,EntryParentProc);
    end;
    CloseHandle(HandleSnapShot);
  end;
  if ParentProcessFound then Result:=ParentProcPath
  else Result:='';
end;
function IsPrime(n: Integer): Boolean;
var
  i: Integer;
begin
  Result:=False;
  if n<2 then Exit;
  Result:=True;
  if n=2 then Exit;
  i:=2;
  while i<(n div i + 1) do
  begin
    if (n mod i)=0 then
    begin
      Result:=False;
      Exit;
    end;
    Inc(i);
  end;
end;
var
  i: Integer;
  ParentName: String;
begin
  ParentName:=GetParentProcessName().ToLower;
  Delete(ParentName,1,ParentName.LastIndexOf('\')+1);
  if ParentName='cmd.exe' then
  begin
    AttachConsole(-1);
    Writeln('');
    for i:=1 to 100 do if IsPrime(i) then Writeln(IntToStr(i)+' is prime');
    FreeConsole();
  end
  else
  begin
    Application.Initialize;
    Application.MainFormOnTaskbar:=True;
    Application.CreateForm(TfrmParentChecker, frmParentChecker);
    frmParentChecker.Label1.Caption:='Executed from '+ParentName;
    Application.Run;
  end;
end.
Main.pas (form with label):
unit Main;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, RzLabel;
type
  TfrmParentChecker = class(TForm)
    Label1: TLabel;
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  frmParentChecker: TfrmParentChecker;
implementation
{$R *.dfm}
end.
This allows me to run my GUI app from a command prompt and display output to the same console where my app was launched.  Otherwise, it will run the full GUI part of the app.
Example output from console window:
I:\Delphi\Tests and Demos\ParentChecker\Win32\Debug>start /wait ParentChecker.exe
2 is prime
3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
23 is prime
29 is prime
31 is prime
37 is prime
41 is prime
43 is prime
47 is prime
53 is prime
59 is prime
61 is prime
67 is prime
71 is prime
73 is prime
79 is prime
83 is prime
89 is prime
97 is prime
I:\Delphi\Tests and Demos\ParentChecker\Win32\Debug>