Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Prüfen, ob Executeable eine Konsolenanwendung ist (https://www.delphipraxis.net/188873-pruefen-ob-executeable-eine-konsolenanwendung-ist.html)

kaju74 15. Apr 2016 07:31

Delphi-Version: 2010

Prüfen, ob Executeable eine Konsolenanwendung ist
 
Hallo.

Irgendwie scheine ich ein Brett vor'm Kopf zu haben, aber wie zum Geier kann ich in Delphi eine EXE prüfen um herauszufinden, ob diese App eine Konsolen-App (Commandline-App) ist? Der File-Header ist in diesem Fall ja auch PE (Win32)...

Danke & lG,
Marc

jaenicke 15. Apr 2016 07:38

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
Da gibt es keine so einfache Unterscheidung soweit ich weiß. Ein Indiz wäre, wenn kein Icon vorhanden ist. Und zur Laufzeit müsste man feststellen können, ob eine Konsole aktiv ist.

Geht es um eine eigene Anwendung oder eine fremde? Bei einer eigenen würde ich schlicht einen Kennzeichner mit einkompilieren, sei es in den Versionsinformationen oder als Ressource angehängt.

uligerhardt 15. Apr 2016 07:57

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
Vielleicht ist hier was dabei?

Der schöne Günther 15. Apr 2016 08:55

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
Ich denke er meint eine fremde. Und ich wüsste auch nicht, dass sich das eindeutig bestimmen lässt. Ich meine- Ich kann eine Konsolenanwendung machen die später doch Fenster anzeigt. Oder Fenster die unsichtbar sind (z.B. für einen Timer). Ist das dann immer noch eine Konsolenanwendung?

kaju74 15. Apr 2016 09:07

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
Naja, es geht darum, den Output einer ausführbaren Datei in einem Fenster anzuzeigen. Dies funktioniert aber nur, wenn die App auch in den StdOut schreibt, was prinzipiell bei Konsolen-Apps der Fall sein sollte. Sobald ich eine GUI-App versuche im Output zu capturen (über CreateProcess und Pipes), dann friert meine App ein. Daher möchte ich vorher erkennen können, ob die App überhaupt eine Konsolen-App ist.

Oder habt ihr andere Ideen?

Danke & lG,
Marc

Der schöne Günther 15. Apr 2016 09:09

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
Ich würde mich ja eher um das "Einfrieren" kümmern und das abstellen ;-)

kaju74 15. Apr 2016 09:41

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
So, habe mir aus den genannten Infos mal was zusammengestrickt, was auf den ersten Blick zu funktionieren scheint:
Code:
class function TNXEnviroment.IsConsoleApp(const FileName: string): Boolean;
var
  Stream: TFilestream;
  Signature: DWORD;
  PE_HEADER: IMAGE_FILE_HEADER;
  OPT_HEADER: IMAGE_OPTIONAL_HEADER;
  DOS_HEADER: IMAGE_DOS_HEADER;
begin
  Result := False;
  if SysUtils.FileExists(FileName) then
  try
    Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
    try
      Stream.Read(DOS_HEADER, SizeOf(DOS_HEADER));
      if DOS_HEADER.e_magic <> IMAGE_DOS_SIGNATURE then // check for MZ
        Exit;
      Stream.Seek(DOS_HEADER._lfanew, soFromBeginning);
      Stream.Read(Signature, SizeOf(Signature));
      if Signature <> IMAGE_NT_SIGNATURE then
        Exit;
      Stream.Read(PE_HEADER, SizeOf(PE_HEADER));
      if PE_HEADER.SizeOfOptionalHeader > 0 then
      begin
        Stream.Read(OPT_HEADER, SizeOf(OPT_HEADER));
        Result := OPT_HEADER.Subsystem = 3;
      end;
    finally
      Stream.Free;
    end;
  except
    { catch all errors }
  end;
end;
Damit dürfte ich erstmal weiterkommen.

Vielen Dank für die Tipps,
Marc

kaju74 15. Apr 2016 09:51

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1335640)
Ich würde mich ja eher um das "Einfrieren" kümmern und das abstellen ;-)

Einfrieren, tut folgender Code:

Code:
    if CreateProcess(nil, PChar(TNXStrings.Format(FileName, Params)), @SecAttributes, @SecAttributes, True, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, Process) then
    try
      { loop while running }
      repeat
        { update running flag }
        Running := WaitForSingleObject(Process.hProcess, 100);

        { loop while data available }
        repeat
          { read output block... }
          Read := 0;
          ReadFile(ReadHandle, Buffer[0], BufSize, Read, nil);
          Buffer[Read] := #0;

          { ...and convert it to ansi }
          OemToAnsi(Buffer, Buffer);

          { callback assigned? }
          if Assigned(Callback) then
            Callback(string(Buffer));
        until (Read < BufSize);

        { process messages }
        Application.ProcessMessages;
      until (Running <> WAIT_TIMEOUT);

      { set result }
      Result := True;
    finally
      { close handles }
      CloseHandle(Process.hProcess);
      CloseHandle(Process.hThread);
    end;
und dabei die Zeile:

Code:
ReadFile(ReadHandle, Buffer[0], BufSize, Read, nil);
Falls einer weiß, warum...?!?

Aber eine normale App gibt ja nichts in StdOut zurück und beendet sich nicht sofort...wahrscheinlich wartet der Prozess dann auf die Beendigung des Mainthreads und kommt dabei nicht weiter...

MArc

himitsu 15. Apr 2016 10:40

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
Die Sufu hattest du auprobiert?
Da gab es vor Kurzem was. :stupid:
http://www.delphipraxis.net/188607-isconsole.html

Zitat:

Ich kann eine Konsolenanwendung machen die später doch Fenster anzeigt
Das ist dann aber auch keine "Konsolenanwendung". :angle2:
Bei denen stellt Windows das Konsolenfenster "vor" dem Start der Anwendung bereit.

Und ja, jede GUI-Anwendung kann auch selber ein Konsolenfenster anzeigen, wenn sie mag.
Konsole/GUI unterscheidet sich allerdings vorrangig nicht durch die Fenster, sondern durch die Prozesssteuerung und wie sie da "standardmäßig" agiert, das wird im Header angegeben.
Konsolenprogramme haben im allgemeinen keine GUI-Fenster oder Message-Behandlung und werden durch andere Signale zum Beenden überredet.

kaju74 15. Apr 2016 12:26

AW: Prüfen, ob Executeable eine Konsolenanwendung ist
 
benutzt ja, so gesucht, nein ;-))

Danke,
Marc

Zitat:

Zitat von himitsu (Beitrag 1335648)
Die Sufu hattest du auprobiert?
Da gab es vor Kurzem was. :stupid:
http://www.delphipraxis.net/188607-isconsole.html

Zitat:

Ich kann eine Konsolenanwendung machen die später doch Fenster anzeigt
Das ist dann aber auch keine "Konsolenanwendung". :angle2:
Bei denen stellt Windows das Konsolenfenster "vor" dem Start der Anwendung bereit.

Und ja, jede GUI-Anwendung kann auch selber ein Konsolenfenster anzeigen, wenn sie mag.
Konsole/GUI unterscheidet sich allerdings vorrangig nicht durch die Fenster, sondern durch die Prozesssteuerung und wie sie da "standardmäßig" agiert, das wird im Header angegeben.
Konsolenprogramme haben im allgemeinen keine GUI-Fenster oder Message-Behandlung und werden durch andere Signale zum Beenden überredet.



Alle Zeitangaben in WEZ +1. Es ist jetzt 01:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz