DLL Erzeugen / COM Schnittstelle erstellen

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

DLL Erzeugen / COM Schnittstelle erstellen

Beitrag von notloesung »

Hallo Ihr,

ich brauche mal wieder eure :!: :!: :!: H I L F E :!: :!: :!:

Bisher habe ich folgende Erfahrungen mit DLL's:
Mit dem VX habe ich bereits dll's erstellt. Das klappt.
Diese habe ich dann aus anderen Xbase Anwendungen aufgerufen (dynamisch über dllload oder statisch). Auch das klappt.

:arrow: Nun stehe ich vor einem P R O B L E M:
Ich muss in Xbase eine Dll erstellen die ich aus einem fremden System aufrufen kann. Dabei handelt es sich um ein Fremdsystem welches mit Visual Basic Script arbeitet. Dort habe ich nicht die Möglichkeit eine Dll über z.B. dllLoad zu laden.
D.h. meine in Xbase erstellte Dll muss ich vorher in Windows registrieren. Nur wie mache ich das? Einfach nur die Dll in das system32 Verzeichnis kopieren und mit regsrv <meinedll.dll> geht es nicht. Ich brauche eine COM Schnittstelle (?)! Aber wie kriege ich diese mit Xbase hin?

Daher die dringende F R A G E:
Wie muss ich vorgehen um in Xbase eine Dll zu erstellen die ich dann in Windows registrieren kann und ohne diese im Programm explizit zu laden benutzen kann?

Ich bin für jede Hilfe dankbar!

Gruß,
Notloesung
Zuletzt geändert von notloesung am Mi, 27. Jun 2007 6:56, insgesamt 1-mal geändert.
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo,

Xbase++ "out of the box" kann das leider nicht. Michael Hoffmanns Produkt Cockpit könnte dir weiterhelfen.

Viele Grüße
Günter
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: DLL Erzeugen / COM Schnittstelle erstellen

Beitrag von AUGE_OHR »

hi,
notloesung hat geschrieben: ich brauche mal wider
das hat doch nichts zu bedeuten, oder ...

Also auf deine Frage : von Xbase++ erstellte *.DLL sind zu nichts und
niemand compatible ...

... trotzdem versuchen es die Jungs ja immer wieder z.b. mit Delphi.
lies mal im Alaska Forum unter "public.xbase++.generic", 10.05.07,
den letzten Thread "Delphi API" von "Pascal Boivin" welche Klimmzüge
er macht um eine Verbindung herzustellen. Ähnliches wird wohl auch
die Demo von DelXBase zu finden unter :
http://www.paritetsoft.ru/downloads/delxbase.zip

besser scheint mir da der Ansatz Boris Borzic zu sein :
"If you create an Xbase++ SOAP server, then you can call any Xbase++
function from Delphi using SOAP."
wie weit das nun auf VB anzuwenden ist müsste man mal nachfragen.

gruss by OHR
Jimmy
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Re: DLL Erzeugen / COM Schnittstelle erstellen

Beitrag von notloesung »

AUGE_OHR hat geschrieben:
notloesung hat geschrieben: ich brauche mal wider
das hat doch nichts zu bedeuten, oder ...
Guten Morgen,

also, ... den habe ich nicht verstanden :lol:

Gruß,
Notloesung
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Guten Morgen,

da es relativ schnell gehen soll habe ich mich entschieden statt einer Xbase Dll eine "normale" Xbase Exe aufzurufen.
Auch wenn das natürlich "arbeiten über Umwege" bedeutet -> die Exe gibt mir keine Werte zurück so wie ich sie von einer Funktion aus einer Dll bekommen könnten.

Wenn dann alles läuft werde ich mir die COM Schnittstelle vornehmen. Dann sollte einiges einfacher werden.
Sicherlich werde ich mir dann die o.g. Toll(s) genauer anschauen. Bisher bin in da so drüber geflogen.

Danke für die Tipps!

Schönen Tag,
Notloesung
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jarek,
Du könntest die Rückgabe natürlich über Errorlevel (teilweise) realisieren...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo notloesung,

da fallen mir "Named Pipes" ein... Für das, was du vorhast, sind die wie geschaffen.

Im Xbase++ - Programm könnte man mit Hilfe einer Bibliothek von Phil Ide ohne grossen Aufwand einen Named-Pipe-Server einbauen.

Für die Client-Seite (VB) gibt es massig Sourcecode im Web, z.B.

How to use named pipes for interprocess communication in Visual Basic .NET or in Visual Basic 2005
http://support.microsoft.com/?scid=kb%3 ... 4&x=12&y=9

How To Use Named Pipes in a Visual Basic 32-bit Program
http://support.microsoft.com/?scid=kb%3 ... 6&x=8&y=16

Viele Grüße
Günter
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Hallo,
Günter Beyes hat geschrieben:Für die Client-Seite (VB) gibt es massig Sourcecode im Web
das werde ich mir mal anschauen denn die Gegenseite (Standard Software) kann nur VBScript :!: nicht VB.
Und da scheint es große Unterschiede zu geben oder anders gesagt: VBScript scheint, im Vergleich zu "reinen" VB, im Funktionsumfang sehr eingeschränkt zu sein (.)

Gruß,
Notloesung
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo,
die Gegenseite (Standard Software) kann nur VBScript
das hatte ich übersehen...

Aber noch ist nicht alles verloren.

Es gibt einen GUI-Server namens GTK, der von VBScript aus mittels Named Pipes gesteuert werden kann.

Das Beispielskript hier scheint mir als Spickzettel nicht schlecht.

Viele Grüße
Günter
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Günter Beyes hat geschrieben:Es gibt einen GUI-Server namens GTK, der von VBScript aus mittels Named Pipes gesteuert werden kann.
Hallo Günter, hallo Ihr!

Hast du irgendwelche Erfahrung mit dem GTK :?:
Ich würde mir den gerne mal näher anschauen, muss aber zugeben, dass ich die Funktionsweise noch nicht wirklich verstanden habe :roll:
(Named Pipes sind wirklich Neuland für mich.)

Grüße,
Notloesung
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

wenn du Grafiken einbinden willst, schau dir mal in der Wissensbasis das RM_Chart an. Entweder über meine Klasse oder über ActiveX.
Diese freie Bibliothek nutzt dir Grafikengine von Windows und macht einem das Leben leichter. Wenn man oben dem Link auf die 3rd European Devcon folgt und die Teilnehmerlisten oder Statistiken ansieht, kann man Beispiele von RM_Chart Grafiken sehen, die über einen Xbase++ Webserver erzeugt werden ... sehr vielseitig :!:
Gruß
Hubert
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Notloesung,

mit GTK hatte ich noch nichts zu tun -- auf den Link ist Google bei der Suche nach Named Pipes in Verbindung mit VBScript gestossen.

Eine Pipe ist nichts weiter als ein Kommunikationskanal zwischen zwei Programmen, der auf Sender- wie auf Empfängerseite so behandelt werden kann, als wäre es eine Datei, die an beiden Endpunkten "shared" geöffnet ist.

Auf deine Anwendung bezogen: Der Client (deine Standardanwendung mit VBScript-Unterstützung) schreibt x Bytes in die Pipe-"Datei", z.B. den Namen einer auf Xbase-Seite aufzurufenden Funktion mit Parameterwerten, und wartet dann auf eine Antwort. Der Server (die Xbase-Anwendung) erkennt, dass Daten in der Pipe bereitstehen, holt diese ab, interpretiert sie, ruft die angeforderte Funktion (so sie denn existiert) mit den gegebenen Parameterwerten auf und schreibt das Ergebnis zurück in die Pipe-"Datei".

Da alle Parameter und das Ergebnis in Zeichenketten umgewandelt werden müssen, bevor man sie in die Pipe-"Datei" schreiben kann, darf man sich ein Protokoll ausdenken, das neben den Datenwerten auch den Datentyp übertragen kann, damit Parameter und Ergebnis korrekt interpretiert werden können.

Wenn die Dienste der Xbase-Anwendung nur lokal benötigt werden und die Funktionsaufrufe nicht allzu vielfältige Parametertypen haben, könnte ich mir vorstellen, dass die Kommunikation beider Programme über Named Pipes einfacher zu realisieren ist als die Alternative, die Xbase-Anwendung zum SOAP-Server zu machen und auf der VbScript-Seite einen SOAP-Client einzubinden.

Aber nun werde ich doch neugierig. Kannst du sagen, was die Xbase-Anwendung für das Standardprogramm tun soll ?

Viele Grüße,
Günter
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Hallo Günter,

erst Einmal vielen Dank für die ausführliche Beschreibung bez. der Pipe-Funktionalität.
Genau diese Art der Beschreibung hilft in manchen Fällen (vor allem dann wenn man das beschriebene noch selbst nie benutzt hat) einiges viel schneller und besser zu begreifen.
Günter Beyes hat geschrieben:Aber nun werde ich doch neugierig. Kannst du sagen, was die Xbase-Anwendung für das Standardprogramm tun soll ?
Ich versuche mal kurz zu fassen was ich machen will.
Einige Bereiche in unserer Fa. werden Software-technisch neu bestückt. Und da man das Rad ja nicht immer neu erfinden muss setzten wir in diesen Bereichen eine Standardsoftware ein (es geht vor allem um die Bereiche FIBU, Einkauf, Lager, ...).
Aber auch in diesen Bereichen gibt es bei uns Prozesse die auf den Betrieb optimiert worden sind. Und genau diese "Sonderlocken" lassen sich ohne Anpassungen (der Standardsoftware) nicht abbilden. Doch für den reibungslosen Ablauf unserer Prozesse sind diese Optimierungen unverzichtbar.

In der neuen Standardsoftware können wir in VBScript eigene Anpassungen machen. Da VBScript funktionstechnisch aber sehr eingeschränkt ist (für mich programmiertechnisch auch gewöhnungsbedürftig) müssen komplexere Anpassungen "ausgelagert" werden. In meinen Fall heißt es: aus der Standardsoftware heraus rufe ich ein eigenes Programm auf (optisch angepasst an die Standardsoftware, für den User also nicht nachvollziehbar das ein anderes Programm gestartet wurde) - in meinem Fall ein Xbase Programm.

Das was mir bisher fehlt ist die "online" Kommunikation der beiden Anwendungen. Aus diesem Grund bin ich eben auf Dll's gekommen - damit ich Rückgabewerte bekomme. Aber wie ich schmerzlich erfahren dürfte geht das mit den Dll's nicht ohne Umwege. Eine normale Exe liefert nun mal nichts Brauchbares zurück.
Wenn es also mit den Pipes klappen würde währe ich einen riesigen Schritt weiter.
Günter Beyes hat geschrieben:Auf deine Anwendung bezogen: Der Client (deine Standardanwendung mit VBScript-Unterstützung) schreibt x Bytes in die Pipe-"Datei", z.B. den Namen einer auf Xbase-Seite aufzurufenden Funktion mit Parameterwerten, und wartet dann auf eine Antwort. Der Server (die Xbase-Anwendung) erkennt, dass Daten in der Pipe bereitstehen, holt diese ab, interpretiert sie, ruft die angeforderte Funktion (so sie denn existiert) mit den gegebenen Parameterwerten auf und schreibt das Ergebnis zurück in die Pipe-"Datei".
Hier denke ich müsste es genau umgekehrt laufen.
Ich befinde mich in der Standardsoftware. Durch eine Aktion X wird ein Xbase Programm gestartet. Im Xbase wird dann eine Verarbeitung angestoßen die dann einen Rückgabewert an die Standardsoftware zurückliefert.
Also denke ich, dass ich bevor ich das Xbase Programm starte einen Pipe Server in VBScript starten muss. Danach starte ich den Pipe Client (Xbase). Der Client liefert dann einen Wert zurück. Dieser wird dann vom Server weiter verarbeitet. Die Pipe muss dann so lange "offen" bleiben bis der Client geschlossen wird. Das merkt dann der Server und beendet sich daraufhin.
Der User merkt davon nichts. Er öffnet einfach nur wie gewohnt seine Fenster. Da die Xbase Programme in diesem Fall an die Optik der Standardsoftware angepasst werden, sieht der User keinen Unterschied.
Er arbeitet sozusagen komplett in der Standardsoftware.

Hoffe es ist zumindest ein wenig verständlich(?).
Falls noch gewünscht dann kann ich einen Prozess noch genauer beschreiben.

Jetzt mache ich mich an die Arbeit und versuche in VBScript einen Pipe Server zu "basteln". Vielleicht finde ich ein wenig Code im Netz ...

Gruß,
Notloesung
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

du könntest wenn nötig auch deine Xbase++ Anwendung beim Systemstart (unsichtbar) starten und den Kanal offen halten bis du ihn brauchst.
Gruß
Hubert
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

brandelh hat geschrieben:du könntest wenn nötig auch deine Xbase++ Anwendung beim Systemstart (unsichtbar) starten und den Kanal offen halten bis du ihn brauchst.
Hallo,

das währe natürlich auch möglich - wobei ich zur der anderen Alternative tendiere.
In diesem Zusammenhang habe ich aber eins nicht verstanden.
In Zukunft werden es mehrere Xbase-Anwendungen sein die aus der Standardsoftware heraus aufgerufen werden. Dann müsste ich doch für jede Xbase-Anwendung einen eigenen Kanal offen halten(?) Oder?

Gruß,
Notloesung
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

ich würde alle Aufgaben in ein Programm stellen und über die übergebenen Daten eine Art von Protokoll aufsetzten z.b.

erste 6 Zeichen = Kontrollid (wenn die falsch ist, alles ignorieren)
6 Byte = Befehl
x Byte = Länge der restlichen Daten
y Byte = restliche Daten

wie lange das X sein muss hängt von der nötigen Länge der Längenangabe für Y zusammen.

Unter VO habe ich mal ein COM Beispiel ausgeführt (Adressserver) und
nicht schlecht gestaunt, dass 2 Programminstanzen die gleichen (dann falschen) Daten angezeigt bekommen. Ob das mit NamedPipes genauso ist weiß ich nicht, mußt halt ausprobieren und aufpassen.
Gruß
Hubert
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo,
Notloesung hat geschrieben:Jetzt mache ich mich an die Arbeit und versuche in VBScript einen Pipe Server zu "basteln".
Die Konvention (MSDN) bezeichnet als Pipe Server ein Programm, das die API-Funktion CreateNamedPipe() aufruft. Um auf das GTK-Skriptbeispiel zurückzukommen -- man müsste mal schauen, ob

Code: Alles auswählen

fso.CreateTextFile("\\.\pipe\out", 0)
hinter den Kulissen tatsächlich eine Named Pipe erzeugt. Das Beispiel suggeriert das zwar, aber ein solches Verhalten scheint zumindest in MSDN nicht dokumentiert zu sein.

Du kannst (wie im GTK-Skriptbeispiel) die Xbase++ - Exe aus VBSkript heraus starten:

Code: Alles auswählen

SET process = CreateObject("Wscript.Shell")

process.Run "xbaseprog.exe"
In Zukunft werden es mehrere Xbase-Anwendungen sein die aus der Standardsoftware heraus aufgerufen werden. Dann müsste ich doch für jede Xbase-Anwendung einen eigenen Kanal offen halten(?) Oder?
Wäre zu prüfen. Pipes haben jedenfalls FIFO-Verhalten -- Lesen "entnimmt" die gelesenen Daten. Auf API-Ebene gibt es zwar die Möglichkeit, vorausschauend zu lesen (um den korrekten Empfänger herauszufiltern) ohne die Daten dabei zu entfernen. Ob das im genannten Beispiel verwendete File System Object so etwas kann, weiss ich nicht -- ich vermute aber eher nein.

Viele Grüße
Günter
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

... kurz vor dem scheitern ... :?

Langsam merke ich dass meine Kenntnisse in der Win-Welt nicht reichen ...
Eigentlich muss ich nur diesen Code hier in VBScript "übersetzen". Aber Pustekuchen :evil:

Notloesung
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

notloesung hat geschrieben:Eigentlich muss ich nur diesen Code hier in VBScript "übersetzen".
Hallo,

VBScript ist eine stark eingeschränkte Version und nicht mit VB6 und VB.NET vergleichbar.
Dein Link zeigt am Anfang auf den COM Server.
Den mußt du aber mit Xbase++ machen. (Phils Beispiel).

Der Client dazu kann vielleicht in VBScript erstellt werden.

Ich habe aber viel zu wenig Ahnung um wirklich helfen zu können. :(
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

wenn alles nichts hilft, mach es doch auf die alte Tour :shock:

1. VBScript erstellt eine Textdatei mit den Infos die du brauchst.
2. VBScript startet die Xbase++ Anwendung mit der Textdatei als Parameter (inkl. Pfad) und wartet bis eine andere Textdatei (name+"OK") erscheint. Sleep - Befehl müsste es geben.
3. Xbase++ Anwendung liest aus der Textdatei die Anweisung und dazu nötige Daten (die Syntax mußt du dir überlegen).
4. Xbase++ berechnet und gibt die Ergebnisse in die ZielTextdatei aus und schließt sich. Eventuell mit Errorlevel ???
5. VBScript sieht die ZielTextdatei und ließt diese ein.
Gruß
Hubert
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Hallo,
brandelh hat geschrieben:wenn alles nichts hilft, mach es doch auf die alte Tour :shock:
da ich den heutigen Tag mit reichlich "rumprobieren" verplempert :roll: habe ist das genau das Ziel welches ich morgen realisieren werde.
Das von dir beschriebenen Prozedere war auch mein erster Gedanke - noch vor den Dll's. Aber man will es ja immer ein wenig besser (und komplizierter) machen ...
brandelh hat geschrieben:Sleep - Befehl müsste es geben.
Genau deshalb wollte ich es erst nicht auf die alte Art und Weise machen. Man stelle sich nun folgendes vor:
Nachdem das VBScript die Xbase-Anwendung gestartet hat legt es sich ja "schlafen". Schließlich wartet es auf die Rückgabe von Xbase in Form einer Datei. Nun hängt sich die Xbase-Anwendung auf. Das kommt schon mal vor :wink:.
Na ja ... und das VBScript wartet und wartet, ...
Irgendwann stellt auch der Anwender fest: "Software ist abgestürzt"

Aber wenn ich ehrlich bin, weis ich gar nicht wie es bei den Named Pipes geregelt ist :?:

Morgen ist also ein neuer Tag - das Ziel: "Der Prototyp muss laufen!"

Gruß,
Notloesung
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

notloesung hat geschrieben:Morgen ist also ein neuer Tag - das Ziel: "Der Prototyp muss laufen!"
Guten Morgen!

... ich denke ich fasse es heute doch noch nicht an ...

:scratch: :coffee2: :clock: Glaube, muss noch einmal darüber nachdenken ... :clock: :coffee2: :scratch:

Gruß,
Notloesung
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Notloesung,

ich habe das VBScript-Beispiel mal nach Xbase++ umgesetzt und Phil Ides Beispielprogramm und auch seine Pipe-Klasse ein bisschen dafür angepasst. Und es läuft !!

Zum Ausprobieren müsstest du Phils Pipe-Klasse wie unten angegeben ändern, damit der Name der Pipe aus der Anwendung heraus definiert werden kann, und die XbPipes-DLL neu erzeugen.

Zum Kompilieren und Ausführen des Beispielprogramms müssen XbPipes.dll, XbPipes.lib und pipes.ch im Pfad liegen.

Offenbar braucht man unter VBScript zwei Pipes für die Kommunikation, obwohl die verwendeten Pipes bidirektional sind.

Sollte das Xbase-Programm mittendrin abstürzen, schliesst das Betriebssystem die Pipes. VBScript sollte dann beim Versuch, auf eine der Pipes zuzugreifen, eine Fehlermeldung zeigen. Ich meine, VBScript erlaubt auch eine programmtechnische Fehlerbehandlung -- immerhin. Dann könnte man im Fehlerfall die Xbase-Exe neu starten.

Ausserdem müsste man mal schauen, ob VBScript Funktionen hat, die chr(), Bin2U() und U2Bin() entsprechen. Wenn nein, müsste Phils Übertragungsformat entsprechend geändert werden, dass es passt.

Viele Grüße,
Günter

Server (NPServer.exe)

Code: Alles auswählen

#include "Common.ch"
#include "inkey.ch"
#include "pipes.ch"
#pragma library("xbpipes.lib")

Function Main()
   local cBuff
   local oServer    := NamedPipeServer():new()
   local oResponder := NamedPipeServer():new()
   local nMsg := 0
   local rc

   SetCursor(0)
   
   oResponder:createPipe(NIL,NIL,"in")
   oServer:createPipe(NIL,NIL,"out")

   ? 'Warte auf pipe: '+oServer:remotePipeName()
   ? 'Antworte auf pipe: '+oResponder:remotePipeName()
   ?

   oServer:acceptConnection()
   
   ? "verbunden"
   
   while inkey() <> K_ESC
      cBuff := oServer:recv()
      if ! empty( cBuff )
         ? 'Empfange Nachricht '+LTrim(Str(++nMsg)) + " " + cBuff
         if (ValType(cBuff) == 'C') .and. (cBuff == 'CLOSE_PIPE')
            oServer:disconnect()
            oResponder:disconnect()
            exit
         endif
      
         // Funktion ausführen
         rc := &(cBuff)
	  
         // Ergebnis zurückgeben
         oResponder:write( var2char(rc) )
      endif
   enddo
   SetCursor(1)

   wait
   
   return NIL
Änderung in Phils npipes.prg

Code: Alles auswählen

METHOD NamedPipeServer:createPipe(nOpenMode, nPipeMode, cPipeName)

   local nMaxInstances := PIPE_UNLIMITED_INSTANCES
   local nOutBuffSize  := 1024 // advisory only, usually ignored
   local nInBuffSize   := 1024 // advisory only, usually ignored
   local nDefTimeOut   := 3000 // timeout to 3 secs
   local pSecurity     := CreateWin32APISecurityStructureForPipes()
   local lOk           := FALSE

   IF cPipeName = NIL
      cPipeName := CreateUniquePipeName()
   ELSE
      cPipeName := '\\.\pipe\' + cPipeName
   ENDIF
Client in Xbase++ à la VBScript

Code: Alles auswählen

#include "activex.ch"
#include "common.ch"

PROC main()

ClientTest()

RETURN

// --------------------------------------------------------------------------

PROCEDURE ClientTest()

LOCAL oProcess
LOCAL oFSO, outpipe, inpipe
LOCAL bError, e
LOCAL nErr
local rc
local cCall

// Server starten
oProcess := CreateObject("Wscript.Shell")
rc := oProcess:Run( "NPServer.exe" )

// Initialisierung des Servers abwarten
Sleep( 100 )

oFSO := CreateObject("Scripting.FileSystemObject")

bError := ErrorBlock( {|e|break(e)} )
begin sequence
   outpipe := oFSO:CreateTextFile("\\.\pipe\out", .F. )
   errorblock( bError )
recover using e
   errorblock( bError )
   if e:description == "0"
      // Fix für fehlende Fehlermeldung
      nErr := e:osCode
	  e:description := DosErrorMessage( bAnd( nErr, 0xFFFF ) )
	endif
    eval( bError, e )
end sequence

bError := ErrorBlock( {|e|break(e)} )
begin sequence
   inpipe := oFSO:OpenTextFile("\\.\pipe\in", 1 )
   errorblock( bError )
recover using e
   errorblock( bError )
   if e:description == "0"
      // Fix für fehlende Fehlermeldung
      nErr := e:osCode
	  e:description := DosErrorMessage( bAnd( nErr, 0xFFFF ) )
	endif
    eval( bError, e )
end sequence

cCall := "4700+11"
? "Funktionsaufruf: " + cCall

rc := CallServer( cCall, outpipe, inpipe )

? "Ergebnis: " + var2char( rc )
?

cCall := "dtoc(date()) + ' ' + time() "
? "Funktionsaufruf: " + cCall

rc := CallServer( cCall, outpipe, inpipe )

? "Ergebnis: " + var2char( rc )
?

// Server beenden
IF outpipe <> NIL
   CallServer( "CLOSE_PIPE", outpipe )
endif

// Pipes schliessen
IF outpipe <> NIL
   outpipe:Close()
endif

IF inpipe <> NIL
   inpipe:Close()
ENDIF

wait

RETURN

// -------------------------------------------------

Function CallServer( string, outpipe, inpipe )

LOCAL rc, nLen

if outpipe <> nil
    // Das von Phil Ide verwendete Format nachgebaut
    
    String := chr(1) + ;                    // Datentyp
                  U2Bin(len(String)) + ;   // Länge des Datenwerts
                  String                          // Datenwert
		  
    String := U2Bin(len(String)) + ;   // Länge der Nachricht
                  String                          // Nachricht
	
    outpipe:Write( String )
endif

if inpipe <> NIL
   sleep(10)

   rc   := inpipe:Read( 4 )     // Länge der Nachricht
	
   rc   := inpipe:Read( 1 )     // Datentyp
	
   rc   := inpipe:Read( 4 )     // Länge des Datenwerts
   nLen := Bin2U( rc )

   rc   := inpipe:Read( nLen ) 
endif

RETURN rc
Zuletzt geändert von Günter Beyes am Di, 03. Jul 2007 13:12, insgesamt 3-mal geändert.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

notloesung hat geschrieben:
brandelh hat geschrieben:Sleep - Befehl müsste es geben.
Genau deshalb wollte ich es erst nicht auf die alte Art und Weise machen. Man stelle sich nun folgendes vor:
Nachdem das VBScript die Xbase-Anwendung gestartet hat legt es sich ja "schlafen". Schließlich wartet es auf die Rückgabe von Xbase in Form einer Datei. Nun hängt sich die Xbase-Anwendung auf. Das kommt schon mal vor :wink:.
Genau, das kommt vor. Daher löscht man beim Programmstart von Xbase++ EXE XPPFATAL.LOG und XPPERROR.LOG (oder wie die Fehlerdateien auch immer heißen) und wenn eine davon auftaucht statt der Ergebnisdatei ist das Programm abgeschmiert.
Gruß
Hubert
notloesung
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 194
Registriert: Fr, 24. Feb 2006 8:09
Kontaktdaten:

Beitrag von notloesung »

Günter Beyes hat geschrieben:ich habe das VBScript-Beispiel mal nach Xbase++ umgesetzt und Phil Ides Beispielprogramm und auch seine Pipe-Klasse ein bisschen dafür angepasst. Und es läuft !!
Hallo Günter,

vielen Dank für deine Arbeit!

Momentan bin ich noch an etwas Anderem dran.
Sobald ich das aber beendet habe werde ich es noch einmal mit den Named Pipes probieren.

Je mehr ich darüber nachdenke desto mehr Vorteile entdecke ich das Problem mit / über die Named Pipes zu lösen.

Ich melde mich sobald es Neuigkeiten gibt.

Gruß,
Notloesung
Antworten