Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Beliebiges Objekt mit Befehlszeile übergeben? (https://www.delphipraxis.net/107205-beliebiges-objekt-mit-befehlszeile-uebergeben.html)

PeterPanino 24. Jan 2008 00:56


Beliebiges Objekt mit Befehlszeile übergeben?
 
Für die Übergabe strukturierter Informationen an ein zu startendes Programm eignet sich die Befehlszeile nur bedingt, da sie m.W. eine begrenzte Länge hat und nur als lineare Zeichenfolge definiert werden kann. Es wäre nützlich, wenn man über die Befehlszeile ein beliebiges Objekt (Datenstruktur) übergeben könnte. Als erstes fiele mir hierzu eine temporäre Datei ein, was aber in der Praxis doch mehr Probleme aufwerfen als Nutzen bringen würde. Ideal wäre die Übergabe eines Zeigers auf ein gemeinsames Objekt im Speicher, aber wie könnte man das realisieren? Wer hat eine Idee?

Phoenix 24. Jan 2008 06:50

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
Hrm.

Wenn Du von einem 'gemeinsamen' Speicherbereich redest willst Du also eigentlich Daten von einem anderen Programm in Deinem weiterverarbeiten?

Das ganze riecht mir in dem Fall stark nach IPC (Interprozesskommunikation), und hat mit der Kommandozeile in der Regel nicht sehr viel zu tun.

Aber hier mal eine Liste der Möglichkeiten, die mir spontan dazu einfallen:

1.) Straightforward und schon genannt: Daten in temporäre Datei schreiben, Dateinamen übergeben

2.) Auch Straightforward: Daten in XML serialisieren, Whitespaces entfernen und so die ganzen XML-Daten in einer Zeile an Dein Programm übergeben. Stellt sich die Frage, wie lang ein Parameter auf der Kommandozeile sein darf.

3.) Etwas, das unter Linux-Systemen sehr gängig ist: StdIn umleiten. Will heissen, die Daten werden in einer Textinterpretation (also auch wieder serialisiert) in die Standardeingabe Deines Programmes gepiped. Ist das gleiche wie wenn Du unter linux z.B. die Ausgabe von ps -aux an grep 'Prozessname' pipest.

4.) Gleicher Speicherbereich: Nennt sich Shared Memory. Allerdings ist es da recht tricky, dann auch die richtige Adresse zu bekommen, denn ggf. wird der Bereich an anderen Speicheradressen in die unterschiedlichen Prozesse gepiped. Man muss hier also z.B. am Anfang des SM Informationen über Offsets zum Beginn des Speichers ablegen.

5.) Named Pipes. Wenn der neue Prozess gestartet wurde kann dieser über einen benannten Kanal diese Daten z.B. selber anfordern. GGf. kann der Name der Pipe als 'Adresse' zu den richtigen Daten übergeben werden.

Das war so das was mir spontan vor meinem ersten Kaffee einfällt, was die Grundprinzipien angeht. Solange Du uns aber nicht noch etwas mehr Informationen lieferst ob die andere Software von Dir ist (IPC via Named Pipes und Shared Mem geht nur dann, wenn beide Kommunikationspartner diese Kommunikationsart implementieren) und was für Daten Du da von A nach B schaufeln musst wird Dir wohl keiner einen Hinweis auf eine möglichst gute Lösung geben können.

Relicted 24. Jan 2008 07:59

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
Ich habs mal folgendermaßen gelöst (gut das programm schickt sich quasi selbst ne message - also einer bereits laufenden instanz):

Starten des 2. Programms,
das erste Programm wartet bis das 2. gestartet ist -> danach schickt es ne windows message mit daten dran an das 2. proggi. dabei kann man dann nen record mit übergeben was in den meisten fällen auch ausreicht.

Delphi-Quellcode:
  // Meldung ausgeben, wenn Programm schon mal gestartet!
  hMutex := CreateMutex( nil,         // pointer to security attributes
                         True,        // flag for initial ownership
                         csAppName ); // pointer to mutex-object name
  if ( GetLastError = ERROR_ALREADY_EXISTS ) then
  begin
    if s <> '' then
    begin
      wnd := FindWindow('xxx', 'xxx');
      if wnd <> 0 then
      begin
        // Daten vorbereiten
        with ACopyDataStruct do
        begin
          dwData := 0;
          cbData := StrLen(PChar(s)) + 1;
          lpData := PChar(s);
        end;
        // Und wech damit..
        SendMessage(wnd, WM_COPYDATA, 0, Longint(@ACopyDataStruct));
      end;
      if ( hMutex <> 0 ) then
        CloseHandle( hMutex );
    end;
    Exit;
  end;

PeterPanino 24. Jan 2008 09:42

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
Mmhh, vielen Dank für die Ideen, werde das mal ausprobieren.

Um die Anforderungen näher zu definieren: Ich möchte von meinem Hauptprogram A aus ein Programm B starten und diesem eine beliebige Datenstruktur übergeben. Die Schnittstelle für die Übergabe der Datenstruktur sollte nicht proprietär sein, sodass sie auch von anderen Programmen ohne Code-Implementation - also nur durch Definition der Befehlszeile - verwendet werden kann. Gibt es eigentlich in Windows keine genormte Schnittstelle, mit der man Objekte übergeben kann?

sirius 24. Jan 2008 09:52

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
Zitat:

Gibt es eigentlich in Windows keine genormte Schnittstelle, mit der man Objekte übergeben kann?
Interfaces; Component Object Model (COM); ActiveX
Edit (IMHO): Und IMalloc ist so ein Interface, wo du dein Objekt platzieren kannst, falls der Objektersteller nicht mehr existiert, wenn der Nutzer darauf zugreift.

marabu 24. Jan 2008 09:56

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
Hallo,

Windows weiß nichts über die Delphi-Objekte. Ich frage mich, warum du ein eigenständiges Programm B entwickeln möchtest, welches auf die Übergabe eines Delphi-Objektes zur Aufnahme seiner Arbeit angewiesen ist. Wäre da nicht ein Package eine besser geeignete Architekturlösung? Wenn die Programme allerdings entkoppelt sein sollen, dann würde ich COM als standardisierten Windows-Mechanismus in Erwägung ziehen.

Freundliche Grüße

Muetze1 24. Jan 2008 10:46

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
Zitat:

Zitat von PeterPanino
Um die Anforderungen näher zu definieren: Ich möchte von meinem Hauptprogram A aus ein Programm B starten und diesem eine beliebige Datenstruktur übergeben. Die Schnittstelle für die Übergabe der Datenstruktur sollte nicht proprietär sein, sodass sie auch von anderen Programmen ohne Code-Implementation - also nur durch Definition der Befehlszeile - verwendet werden kann. Gibt es eigentlich in Windows keine genormte Schnittstelle, mit der man Objekte übergeben kann?

Da die anderen Programme dein Objekt nicht kennen, würden sie es niemals ansprechen geschweige denn ansprechen können. Damit lässt sich der kursive, fette Textteil direkt ausschließen.

Und zu der Liste der Windows Schnittstellen dazu noch zwei weitere: Clipboard, DDE

Tyrael Y. 24. Jan 2008 11:16

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
Wenn dein Hauptprogramm kein Service ist eignet sich die schon genannte Methode über Windowsnachrichten dafür hervorragend.

Du benutzt WM_COPYDATA dafür, das nutzt für beide Prozesse denselben Speicher und ist genau für so etwa vorgesehen.

Eine Kommunikation in beide Richtungen ist damit möglich.

Delphi-Quellcode:
var LCopyDataStruct : TCopyDataStruct;
...
...
SendMessage(HandleDesZiels, WM_COPYDATA, EineZahl_BeliebigeDaten, LongInt(@LCopyDataStruct));
PostMessage oder SendMessage dafür nutzen, je nach dem was man erreichen möchte.

PeterPanino 24. Jan 2008 11:32

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
Zitat:

Zitat von Tyrael Y.
Wenn dein Hauptprogramm kein Service ist eignet sich die schon genannte Methode über Windowsnachrichten dafür hervorragend.

Du benutzt WM_COPYDATA dafür, das nutzt für beide Prozesse denselben Speicher und ist genau für so etwa vorgesehen.

Eine Kommunikation in beide Richtungen ist damit möglich.

Delphi-Quellcode:
var LCopyDataStruct : TCopyDataStruct;
...
...
SendMessage(HandleDesZiels, WM_COPYDATA, EineZahl_BeliebigeDaten, LongInt(@LCopyDataStruct));
PostMessage oder SendMessage dafür nutzen, je nach dem was man erreichen möchte.

Können Windows-Nachrichten unter ungünstigen Bedingungen (z.B. Betriebssystem ausgelastet) nicht auch schon mal verloren gehen?

sirius 24. Jan 2008 11:43

Re: Beliebiges Objekt mit Befehlszeile übergeben?
 
(WM_CopyData geht nur über Sendmessage)

Das so etwas verloren geht, wäre mir neu (zumindest wenn der Adressat existiert)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:29 Uhr.
Seite 1 von 2  1 2      

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