Entwickler-Ecke

Windows API - Informationen an aufrufende Kommandozeile zurück geben


daywalker0086 - Do 28.01.16 12:28
Titel: Informationen an aufrufende Kommandozeile zurück geben
Hallo Leute, ich brauche mal wieder eure Hilfe.
ich habe ein Windowsform Programm, also ganz normales Programm.
Das wird über die Kommandozeile mit entsprechenden Parametern aufgerufen.
Soweit funktioniert das auch super.

Es soll aber auchwenn es mit seiner Arbeit fertig ist Informationen an die aufrufende Kommandozeile zurück geben, zum Beispiel Fehlercodes.
Gibt es da Möglichkeiten Werte zurück zu geben? Mit welchen Funktionen/Eigenschaften kann man das machen?

Ist es auch möglich während der Abarbeitung ständig Informatioen zurück zu geben?

Ja das wärs schon ;)

Falls da jemand Antworten hat wär das schön

Grüße Christian


Narses - Do 28.01.16 14:56

Moin!

Eigentlich sollte es auch in einer VCL-Anwendung möglich sein, über die (Applikations-)Globale Variable "ExitCode" einen Return-Code an die aufrufende Kommandozeile zurück zu geben (hab ich aber glaub ich noch nicht getestet, wenn dann war das gleich eine Konsolenanwendung, da klappt das definitiv). :nixweiss:

Für laufende Status-Informationen musst du halt mit dem Prozess "reden". Ein gutes Stichwort ist IPC (InterProzessCommunication) zum Suchen. :les: :think:

cu
Narses


mandras - Fr 29.01.16 01:30

Witziges Verhalten, ich werde es nun aber nicht weiter verfolgen.

Also:
Folgender Text in der Projektdatei setzt den Exitcode korrekt:

Delphi-Quelltext
1:
2:
3:
4:
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
  exitcode := 5;

Das läßt sich dann in der Kommandozeile auch per %errorlevel% abfragen.

Interessant ist eben:
Einfaches Aufrufen dieser VCL-Anwendung von CMD aus startet diese, läßt sie offen und kehrt sofort zur Eingabe
des nächtsten Befehls per CMD zurück.

Aufruf aus BAT-Datei startet nun die Anwendung und macht erst weiter wenn die Anwendung beendet wurde.

Ist bestimmt irgendwo im MSDN dokumentiert dieses abweichende Verhalten, näheres weiß ich aber nicht.

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


tomte - Fr 29.01.16 10:23

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:

Aufruf aus BAT-Datei startet nun die Anwendung und macht erst weiter wenn die Anwendung beendet wurde.

Ist bestimmt irgendwo im MSDN dokumentiert dieses abweichende Verhalten, näheres weiß ich aber nicht.



Das ist das normale Verhalten bei einer BAT-Datei. Das kannst du auch mit calc.exe testen

Wenn in der BAT-Datei du nur calc.exe schreibst, dann wird auf das Ende des Programms gewartet.
Aber wenn du statt dessen start calc.exe schreibst, dann wird nicht auf das Ende des Programms gewartet.


daywalker0086 - Mi 26.10.16 15:52

Hallo Leute,
ich melde mich hier nochmal zurück.
Die ursprüngliche Sache funktioniert soweit.
Das Programm wird mit

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
   if ShellExecuteEx(@SEInfo) then begin
    repeat
    Application.ProcessMessages;
    GetExitCodeProcess(SEInfo.hProcess, ExitCode) ;
    until (ExitCode <> STILL_ACTIVE) or
    Application.Terminated;
                ShowMessage(inttostr(exitcode)) ;

augerufen und ich bekomme den Exitcode auch nach Programmende angezeigt.
Jetzt würed ich aber gerne während das Programm läuft Informationen an das aufrufende Programm übermitteln über den aktuellen Zustand.
Ich kann beide Programme verändern, ist jetzt nur die Frage wie?

Hat da wer noch eine Idee?

Grüße Christian


Nersgatt - Mi 26.10.16 16:07

Da gibt es verschiedene Möglichkeiten, 2 Prozesse miteinander kommunizieren zu lassen.
Named Pipes, Mailslots, oder selbst etwas für TCP/IP programmieren (dann wäre auch eine Statusanzeige über das Netzwerk möglich).
Wenn nur 2 lokale Prozesse kommunizieren sollen, würde ich vermutlich zu den Named Pipes greifen.

Generell kannst Du Dir hier einen Überblick über die Optionen verschaffen:
https://de.wikipedia.org/wiki/Interprozesskommunikation


daywalker0086 - Mi 26.10.16 16:36

Also ich denke mit Ostmessages ist es das einfachste einfach eine Zahl zu übermitteln.
Jetzt will ich mir einfach erstmal in meinem Hauptprogramm selbst NAchrichten schicken:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.Button3Click(Sender: TObject);
var
   wndMain, wndChild: HWND;
   txt: string;
const
   MY_MESSAGE = WM_USER + 4242;
begin
txt := 'Hello World';
   wndMain :=  FindWindow(nil,'universelles Programmier-Tool');
   if wndMain <> 0 then
   begin
   showmessage('gefunden');
   //SendMessage(Form1.Handle, MY_MESSAGE, 0, DWORD(PChar(txt)));
   postmessage(wndMain,wm_user,0,10);
   end;
end;


Wie kann ich jetzt die Message anzeigen lassen?


Nersgatt - Mi 26.10.16 16:43

Du kannst eine Procedure deklarieren, die auf diese Message reagiert:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private
    procedure OnMyMessage(var Msg: TMessage); message MY_MESSAGE;

[...]

procedure TForm1.OnMyMessage(var Msg: TMessage);
begin

  Weltherrschaft_erringen();

end;


Die Konstante für MY_MESSAGE würde ich dann an einer Stelle etwas globaler deklarieren, nicht in dem Button3Click.


daywalker0086 - Mi 26.10.16 16:46

Alles Roger, läuft soweit.

Was nehm ich denn als Konstante für WM_mymessage ?
Kann ich da irgendeine Zahl nehmen? Warscheinlich nicht?
Ich will ja dann später Programmübergreifend kommunizieren und dqnn muss in beiden Programmen ja der Wert gleich sien oder?


Nersgatt - Mi 26.10.16 17:45

Üblicherweise nimmt man WM_User + x, wobei Du das x selbst festlegen kannst.