Skripts
Zuletzt geändert: 11.06.2023 10:06

Skripts #

Zielsetzung #

Über die EULANDA-Warenwirtschaft soll über Script-Befehle direkt ein Telnet-Server gesteuert werden.

Hierüber lassen sich Anzeigetafeln, ePaper-Displays, Waagen und viele netzwerkfähigen Geräte steuern — vorausgesetzt diese lassen sich über Telnet steuern.

Aber auch Router enthalten oft einen Telnet-Server. Bei einer anstehenden Übertragung zum Beispiel zu einem SHOP-Server oder dem Versenden einer EDI-Nachricht mittels AS2 lassen sich mit einem Telnet-Client die Firewall-Regeln im Router ein- bzw. ausschalten.

Was liegt näher, als dass das Programm, das die Kommunikation mit den Servern aufbaut — also EULANDA — diese Aufgabe übernehmen zu lassen. Dies kann dann genau im richtigen Moment, nämlich vor der Übertragung, geschehen.

Hierzu ist ein Telnet-Client notwendig. Man kann natürlich die Windows-Bordmittel verwenden, aber diese erlauben es beispielsweise nicht das Passwort zu übergeben und skriptfähig sind diese auch nicht.

Wir haben uns deshalb entschlossen einen skriptfähigen Telnet-Client in EULANDA zu integrieren, der diese Aufgaben erfüllen kann.

Der Telnet-Client eignet sich aber für fast jegliche Art der Telnet-Kommunikation und enthält nebenbei auch ein einfaches interaktives Terminal, speziell zum Testen von Telnet-Befehlen. Das Skript-Objekt zum Telnet-Client ist ab EULANDA-Version 6.0.26 als optionales Modul verfügbar. Zur Nutzung wird eine zum Hauptsystem passende Seriennummer benötigt.

Für die Nutzung der API benötigt der Entwickler eine spezielle Entwickler-Lizenz und erhält neben den technischen Unterlagen eine NFR+1 Lizenz sowie ein eindeutiges Entwickler-Kürzel zur Erstellung eigener Module. Die Preise und genauen Bedingungen erfragen Sie bitte beim Vertrieb.

EULANDA dient als ausführender Scripting-Host. Hierzu stellt EULANDA diverse Objekte bereit die Zugriffe auf interne Bibliotheken, Bildschirminhalte sowie Kommunikations- und Verschlüsselungsobjekte. Das Basisobjekt ist das Applikations-Objekt, welches die verschiedenen Mandanten - die Clients - verwaltet. Das Client-Objekt hat über seine “CreateObject”-Methode die Möglichkeit die dem Mandanten zugeordneten Objekte zu instanziieren. Zu diesen Objekten zählen Dialogobjekte, wie der Multi-Dialog, Kommunikations-Objekte wie SMTP, FTP, TELNET aber auch SSH Verschlüsselungs-Objekte wie das SFTP-Protokoll.

EULANDA stellt im Wesentlichen einen Baukasten um wesentliche Funktionen rund um die das Thema Warenwirtschaft zur Verfügung mit dem Apps bzw. Plug-Ins erstellt werden können, die das Basisprogramm um spezielle Funktionen erweitern.

EULANDA selbst muss entsprechend für spezifische Projekte nicht erweitert werden, sondern diese Module greifen lediglich auf den internen Baukasten zurück. Diese Objekte werden auch intern innerhalb der Warenwirtschaft benutzt, so dass diese Objekte robust und ausgereift sind.

Man unterscheidet interne und externe Skripts. Die Unterschiede werden im nächsten Kapitel anhand eines Beispiels beschrieben.

Interne Skripts #

Interne werden in der EULANDA-SQL-Registry gespeichert und beim Start von EULANDA initialisiert. Entsprechend sind alle Methoden und Variablen global, so dass sich empfiehlt ein eigenes Präfix vor die Methoden zu setzen.

Ein Aufruf ist als Menü-Action oder aus einem beliebigen anderen EULANDA-Skript möglich. Zusätzlich verfügt EULANDA über einen optionalen internen Taskmanager mit Hintergrundverarbeitung. Über eine eigene SQL-Funktion kann die Prozedur aktiviert werden.

Menüaction #

Ein Menüaction erzeugt im Hauptmenü von EULANDA einen Menüeintrag, der mit einem bestimmten Script innerhalb der SQL-Registry verbunden ist. Menüactions sind im Ordner “Actions” unterhalb des Registry-Baumes "\OBJECTS\DATAOBJECTS\Eulanda.Adresse" für den Bereich Adressen angesiedelt.

img

Menü-Action für Adressen

Hier kann ein beliebiges Action angelegt werden. Der erste Teil des Namens enthält das von EULANDA vergebene Entwicklerkürzel, hier im Beispiel “esol”. Gefolgt der Name das Hauptobjekts und einem eindeutigen Action-Namen. Unser Beispiel verwendet “esol.Adresse.HelloWorld”.

Es ist absolut wichtig ein eigenes Entwicklerkürzel zu beantragen, da unbekannte Einträge in der SQL-Registry sowie nicht registrierte Einträge beim Update ohne Vorwarnung gelöscht werden.

Auf der rechten Seite kann in der “ActionClass” angegeben werden, wo im Menü der Menüpunkt erscheinen soll. Im Eintrag “CommandText” ist das eigentliche Skript, dazu später mehr. Über “IconURL” kann auf ein beliebiges in EULANDA gespeichertes Icon zugegriffen werden. Eine Liste der gespeicherten Icons kann man sich im Entwickler-Modus abrufen. Über Language gibt man die Scriptsprache an, in der das unter “CommandText” gespeicherte Skript erstellt ist. In diesem Beispiel wird “VBScript” verwendet. Jedem Menüeintrag kann ein Tastaturkürzel zugeordnet werden, wobei man natürlich darauf achten muss, dass die Kombination noch frei ist. Über Titel wird der Text des Menüeintrags vorgegeben und der Type gibt an um welche Art von Action es sich handelt. “iScript” betrifft die Gruppe der Windows-Skriptsprachen. Standardmäßig wird Windows mit den zwei Sprachen “VBScript” und “JScript” ausgeliefert. Windows erlaubt aber das Hinzufügen weitere WSH-Skriptsprachen.

In unseren Beispielen verwenden wir der Einfachheit halber immer “VBScript” verwendet, da dies viele Entwickler von der Office-Makroprogrammierung her schon kennen.

Nach dem Neustart von EULANDA wird das Skript eingebunden und der neue Menüpunkt erzeugt.

img

Das erste Skript im Action-Bereich von Adressen

Wenn alles richtig gemacht wurde, sollte bei Aufruf des Menüpunkts eine Ausgabebox am Bildschirm erscheinen.

img

Aktion mit Telnet-Objekt

Das erste Skript #

In diesem Beispiel verwenden wir ein ganz einfaches Skript, nämlich “HelloWorld”.

option explicit
Sub Main()
    Dim Telnet
	Set Telnet = Client.CreateObject("TELNETLIB")
	Telnet.HelloWorld
	Set Telnet = nothing
End Sub
Main()

Es wird empfohlen die Direktive “option explicit” stets voranzustellen, da hierdurch die wichtigsten Fehler gemeldet werden. Jede Variable die angesprochen wird muss zuvor deklariert werden.

Als weiteres wird empfohlen jedes Skript in eine Funktion oder Methode zu verpacken, da hierdurch instanziierte Objekte nicht wieder freigegeben werden müssen. In dem Fall kümmert sich das Runtime-System beim Beenden einer Funktion oder Methode alle Objekte wieder freizugeben.

In oberen Beispiel wird die Telnet-Bibliothek über das “Client”-Objekt erzeugt. Der “Client” ist eines der globalen EULANDA-Objekte, die bei internen Skripts, also denen die in der SQL-Registry ausgeführt werden, immer vorhanden ist. Neben dem “Client”-Objekt gibt es zahlreiche andere wie “dataset”, “conts” und “ellib”.

Bei externen Skripts müssen die globalen Objekte zunächst instanziiert werden.

Externe Skripts #

Ein externes Skript wird vom Betriebssystem aus gestartet und kann z.B. von einer Kommandozeile oder in der Aufgabenplanung des Arbeitsplatzes gestartet werden. Externe Skripts lassen sich hierdurch einfach in beliebig andere Umgebungen integrieren.

Auch bei externen Skripts dient EULANDA zum Ausführen der speziellen Objekte wie “client”, “consts” und “telnetlib”. Objekte werden unter Windows-Skriptsprachen mit “CreateObject(“Objekt-Name”)” instanziiert. Damit Windows die Hostanwendung, die dieses Objekt ausführt kennt, muss die Anwendung zuvor einmalig registriert werden.

Registrierung von EULANDA als Script-Host #

Zur Registrierung wird die Windows-Kommandozeile im Administrator-Modus geöffnet. Am Prompt “C:>” wird der komplette Pfad inkl. des EULANDA.EXE und dem Parameter “/REGISTER” eingegeben. Der Pfad kann auch ein UNC-Netzwerkpfad sein.

C:\>\\mein-server\eulanda\eulanda.exe\register

Durch Eingabe dieser Zeile wird EULANDA einmal gestartet, und beendet sich anschließend wieder. Durch diese Funktion registriert sich EULANDA in der Windows-Registry für alle Objekt-Klassen, die EULANDA unterstützt. Eine davon ist das Objekt “TELNETLIB”.

Von einem Windows-PC aus kann es nur eine EULANDA.EXE geben, die die Objekte ausführt und damit registriert werden kann. Dies ist wichtig zu wissen, da auf einem PC normalerweise beliebig viele verschiedene EULANDA.EXE koexistieren können. Da EULANDA mehrmandantenfähig ist, kann man auch einen Ordner mit EULANDA.EXE dort aber beliebig viele UDL-Dateien ablegen, die als Aliase dann nutzbar sind.

Das erste externe Skript #

Je nach Einrichtung von Windows wird die Extension von Dateien nicht angezeigt. Diese sollten in jedem Fall angezeigt werden, dies kann unter den Ordner-Optionen eingestellt werden.

img

Ordneroptionen

In einem Text-Editor wie dem Notepad wird folgender Text angelegt und mit der Datei-Endung “.vbs” gespeichert.

option explicit
Dim app, client
Sub Main()
	Dim Telnet
	Set app = CreateObject("Eulanda.Application")
	Set client = app.Clients("Eulanda GmbH")
	Set Telnet = client.CreateObject("TELNETLIB")
	Telnet.HelloWorld
	Set Telnet = nothing
End Sub
Main()

Gegenüber den internen Scripts gibt es bei externen einige zusätzliche Dinge zu beachten. Die in EULANDA enthaltenen Script-Objekte können nur über den Client Instanziiert werden. Das Client-Objekt ist ein Mandant, also eine Datenbank. Damit man diesen bekommt muss zunächst die EULANDA-Anwendung als Objekt instanziiert werden. Dies ist das einzige Objekt, welches direkt aus einem externen Skript mit dem Standard-Befehl “CreateObject” instanziiert werden kann.

Das Applikations-Objekt hat eine Methode ein Client-Objekt zu erzeugen. Als Parameter wird der Alias benötigt, dies ist der Name der im EULANDA-Startmenü aufgeführt wird.

Der Client wiederum hat eine lokale “CreateObject”-Methode und erlaubt es damit alle in EULANDA definierten Objekte zu instanziieren ohne dass diese einzeln im Windows-System registriert werden müssen.

Es wird empfohlen die internen Objekte wie “client”, “app” usw. global im Skript zu deklarieren. Hierdurch können diese von beliebigen Funktionen und Methoden des Skripts verwendet werden.

Wichtig ist, dass die Instanziierung dieser Objekte wie “app”, “client” usw. nur in externen Skripts erfolgt. In internen Skripts existieren diese bereits von Haus aus, sie dürfen diese Namen auch nicht in internen Skripts erneut deklarieren.

Oft werden externe Skripts zum Debuggen benutzt. Man muss dann die notwendigen Hilfsobjekte “app” und “client” einfügen und immer darauf achten, dass man diese beim “Rückbau” in die SQL-Registry - also bei internen Skripts - wieder löscht oder auskommentiert.

Möchte man identische Skripts erstellen, die sowohl intern als auch extern funktionieren, so muss man diese als Hybrid-Skripts definieren. Diese haben etwas mehr Overhead, aber am Ende sind diese für alle Projekte identisch, was äußerst praktisch ist.

Hybrid-Skripts #

Wenn ein Skript ohne Veränderung intern als auch extern genutzt werden kann, spricht man von Hybrid-Skripts. Der Trick dabei ist eine Erkennung, die prüft, ob das Skript intern oder extern ausgeführt wird. Im Fall der externen Ausführung werden die Hilfsobjekte deklariert und auch gleich instanziiert.

VBScript lässt keinen globalen DIM-Befehl in einem IF-Zweig zu, er wird schlicht weg immer ausgeführt. Der Trick ist, dass der Befehl ExecuteGlobal verwendet wird. Er erlaubt es einen String als Quelltext zu behandeln, und dieser kann dann in einer IF-Bedingung bei Bedarf ausgeführt werden.

Das Beispiel von “HelloWorld” sieht in Hybrid-Form wie folgt aus:

option explicit
Dim EulandaObjStr : EulandaObjStr = _
	"Dim app, client, ellib, consts, dataset" & vbCrLf &_
	"Set app = CreateObject(""Eulanda.Application"")" & vbCrLf &_
	"Set client = App.Clients(""Eulanda GmbH"")" & vbCrLf &_
	"client.active = True" & vbCrLf &_
	"Set ellib = Client.createobject(""Context"").ellib" & vbCrLf &_
	"Set consts = Client.createobject(""Context"").consts" & vbCrLf &_
	"Set dataset = Client.createobject(""CurrentDataset"", ""Eulanda.Adresse"")"
Sub EulandaObj
	Dim dummy
	dummy = False
	on error resume next
	if Wscript.ScriptFullName <> "" Then dummy = True
	if err.number = 0 Then ExecuteGlobal EulandaObjStr
	on error goto 0
end Sub
EulandaObj
Sub Main()
	Dim Telnet
	Set Telnet = client.CreateObject("TELNETLIB")
	Telnet.HelloWorld
	Set Telnet = nothing
End Sub
Main()

Das interessante hierbei ist, dass die Hauptroutine genau so einfach ist wie bei einem internen Skript. Lediglich der graue Textblock wird vor das gesamte geschoben und bleibt bei nahezu allen Anwendungen gleich. Der Name des Mandanten im obigen Beispiel ist “Eulanda GmbH” und muss entsprechend einmal angepasst werden. Wenn Sie mit einer speziellem EULANDA arbeiten kann dies auch ein Default-Alias sein - z.B. EULANDA_Debug.udl, so dass der Name dann immer identisch wäre.

Der Einbindungscode am Anfang des Skripts instanziiert gleich weitere Grundobjekte aus EULANDA und startet mit “client.active = true” auch gleich die Eulanda.exe mit dem richtigen Mandanten. Sollte EULANDA bereits gestartet sein, wird die aktive Instanz verwendet, ansonsten dauert es zwar einige Sekunden länger, aber ohne weiteres Zutun wir der Mandant gestartet so dass das Skript fehlerfrei ausgeführt werden kann.

Über diesen Mechanismus lassen sich Skript-Jobs zeitsteuern oder mit sonstigen Betriebssystem-Aufgaben kombinieren.

Skripts debuggen #

Skripts lassen sich wunderbar mit dem Programm Vbsedit von der Firma Adersoft erstellen und debuggen. Jeder der etwas mehr mit VBScript macht, sollte sich dieses kleine aber sehr leistungsfähige Tool anschaffen. Es kostet ca. 50 EUR und kann direkt bei dem Hersteller in Frankreich online bezogen werden. Die Installation ist denkbar einfach und nach dem Neustart des PCs kann ein Hybridskript sofort im Debugger gestartet werden. Neben dem komfortablen Editor enthält das Paket auch gleich duzende interessante Vorlagen zum Zugriff auf die verschiedensten Windows-Funktionen bereit.

img

Hybrid im Debugger VBSsedit

Im oberen Bild wurde ein Breakpoint gesetzt, mit Vbsedit lassen sich Variablen und Objektstrukturen darstellen. Insgesamt ein sehr rundes Produkt. Die Dokumentation zum Editor / Debugger finden Sie in dessen Online-Hilfe.

Neben Vbsedit gibt es noch PrimalScript von der Firma Sapien. Dieser Editor bzw. Debugger liegt bei ca. 400 EUR und kann neben VbScript und JScript noch mit ca. 30 weiteren Skriptsprachen wie Powershell, Ruby usw. umgehen. PrimalScript ist sicherlich deutlich leistungsfähiger, aber auch entsprechend unhandlicher. Wer nur VBScript editieren und debuggen möchte ist mit Vbsedit bestens bedient. Während PrimalScript meines Wissens nach nur auf einem PC installiert werden kann (Aktivierung erforderlich) wird Vbsedit registriert und darf mehrfach auf eigenen System installiert werden.

Skripts im Hintergrund ausführen #

Die Voraussetzung zur Ausführung von Skripts im Hintergrund ist, das es sich um interne Skripts handelt. Also Skripts die in der SQL-Registry gespeichert sind. Die Hintergrundverarbeitung ist nur in der EULANDA®-Enterprise oder als Zusatzoption zu einer EULANDA®-Professional möglich.

Eine EULANDA®-Instanz muss hierzu im Desktop-Modus auf einem unterstützten Windows-PC gestartet sein, dies könnte auch ein virtueller PC sein.

Vorbereitung #

Die Hintergrundverarbeitung erfordert einige Vorbereitungen. Zum einen muss die Hintergrundverarbeitung in “Zubehör\Einstellung\Features und Programmfunktionen” aktiviert sein.

img

Features und Programmfunktionen

Des Weiteren benötigt man einen UID-Key, also eine weltweit eindeutige Zufallszahl. Diese erhält man über verschiedene Wege, unter anderem auch direkt aus einem VBScript heraus.

Über folgende kleine Funktion erhält man eine weltweit eindeutige und damit zufällige UDI:

Function UID
	Dim Scriptlet, St
	Set Scriptlet = CreateObject("Scriptlet.TypeLib")
	St = CStr(Scriptlet.Guid)
	St= Left(St, InStr(St, "}"))
	UID = Mid(St,2,Len(St)-2)
End Function

Diese Funktion hat die “66904AE0-E876-4EE1-9165-91D740EBA91C” ausgegeben, welche im folgenden Beispiel verwendet wird.

Die Hintergrund Verarbeitung basiert auf einer SQL-Funktion, die als Trigger dient. Auf diese Weise lassen sich Ereignisse am Frontend, als der EULANDA über VBScript behandeln.

Wird der folgende Abschnitt als “.cnreg”-Datei gespeichert, so lässt sich die Konfiguration per Doppelklick in die EULANDA-SQL-Registry importieren.

CnRegEdit1
[\SYSTEM\SERVICES\Services\{66904AE0-E876-4EE1-9165-91D740EBA91C}]
"Active"=dword:00000001
"Autostart"="pcnames=BOND"
"Callback"="TelnetDemo.BackgroundTest"
"Callback.Language"="VBScript"
"Caption"="Telnet-Service"
"CommandText"="set @e = 1"
"CommandTextParams"="@e int OUT"
"ControlParamName"="@e"
"Name"="esol.TelnetDemo.Heartbeat"
"Timer"="Interval=1s;Startup Delay=5s"
"Type"="SqlProc"

Würde der PC “BOND” heißen und EULANDA würde neu gestartet, so wird nach einer Verzögerung von 5 Sekunden, und dann im Sekundentakt der “CommandText” ausgeführt. Das kann eine SQL-Funktion oder ein statischer Befehl sein. Ist das Ergebnis “1” so wird ein internes lokal zur EULANDA in der Sektion “LIB” gespeichertes Skript gestartet. Die VBScript-Methode müsste in der Unit-“TenetDemo” gespeichert und den Namen “BackgroundTest” haben.

In der Methode “BackgroundTest” könnte dann ein Telnet-Skript enthalten sein, dass z.B. das zum Beispiel das Gewicht einer Waage ausliest oder Alarme aus der Firewall und diese dann in der EULANDA-Startseite anzeigt.