Version 1.1 von jklein am 2024/08/13 08:19

Zeige letzte Bearbeiter
1 {{aagon.priorisierung}}
2 160
3 {{/aagon.priorisierung}}
4
5 {{aagon.floatingbox/}}
6
7 = Ausgangslage =
8
9 In diesem Anwendungsfall wird Ihnen anhand einer Schritt-für-Schritt Anleitung aufgezeigt, wie Sie mithilfe eines Client Commands den [[Form Editor>>doc:65.ACMP-Solutions.Client Commands.Client Command erstellen.Client Commands neu hinzufügen.Client Command Editor.Commandlist.Dialogs.Der Form Editor.WebHome]] über die AESB Schnittstelle an einen Client senden können. Dabei werden die verfügbaren Clients aus der Datenbank geladen und in einer Liste angezeigt. Über ein Suchfeld kann der Benutzer nach bestimmten Client Commands filtern. Die Treffer werden aus der Datenbank geholt und ebenfalls in einer Liste angezeigt. Um das versehentliche Absenden des Client Commands zu verhindern, muss der Benutzer noch eine Checkbox anhaken. Diese dient dazu zu bestätigen, dass der ausgewählte Client und das ausgewählte Client Command korrekt sind.
10
11 Zur besseren Verständlichkeit wird der Inhalt des //Form Editors //größtenteils in der Code-Ansicht erläutert.
12
13 {{figure}}
14 (% style="text-align:center" %)
15 [[image:66_Use Case Client Commands_AESB Code Ausschnitt_906.png]]
16
17 {{figureCaption}}
18 Code-Ansicht für den nachfolgenden Client Commands Use Case
19 {{/figureCaption}}
20 {{/figure}}
21
22 {{aagon.infobox}}
23 Lesen Sie hier nach, wie Sie [[AESB installieren>>doc:AESB.19.AESB installieren, konfigurieren und aktualisieren.AESB Core-Komponenten installieren.WebHome]] können und wie die Komponenten [[ACMP und AESB miteinander verbunden>>doc:AESB.19.AESB installieren, konfigurieren und aktualisieren.SICS-Verbindung konfigurieren.WebHome]] werden.
24 {{/aagon.infobox}}
25
26 == Skript auswählen ==
27
28 1. Navigieren Sie ins Modul //Client Commands// > //Erstellen//.
29 1. Klicken Sie in der Ribbonleiste auf //Hinzufügen//. Es öffnet sich der Client Command Editor, in dem Sie entscheiden müssen, ob es sich um ein Console- oder Clientskript handelt. In diesem Fall wählen Sie das Console Skript aus.
30
31 == Command //Set project variable //auswählen und bearbeiten ==
32
33 1. Wählen Sie aus der Commandliste das Command //Variables //> //Set project variable// aus.
34 1. Öffnen Sie den Befehl per Doppelklick und öffnen Sie nun den Tab //Allgemein//.
35 1. Tragen Sie unter //Beschreibung der Aktion //einen Namen ein. In diesem Beispiel wird „Hier den AESB Benutzernamen setzen“ eingefügt. Alle weiteren Konfigurationsmöglichkeiten in diesem Tab müssen nicht angepasst werden.
36 1. Wechseln Sie in den Tab //Details//.
37 1. Klicken Sie unter der Variableneinstellung auf das Icon neben dem Variablennamen.
38 1. Optional: Legen Sie eine neue Variable unter den //Aktionen //an. Benennen Sie diese „USERNAME“ und klicken Sie auf das Plus-Icon. Klicken Sie anschließend auf den //OK //Button, um den Schritt abzuschließen und damit der Eintrag als Variablenname gelistet wird.
39
40 {{aagon.infobox}}
41 Dieser Schritt ist optional, sollte sich diese Variable bisher nicht bei Ihnen im System befinden und angelegt worden sein.
42 {{/aagon.infobox}}
43
44 7. Fügen Sie unter dem Feld //Einzeiliger Text //den Begriff „Operator“ ein. Dieser wird hier als Erkennungsmerkmal für den Benutzernamen benötigt.
45 8. Klicken Sie im Anschluss auf //OK//.
46
47 {{figure}}
48 (% style="text-align:center" %)
49 [[image:66_Use Case Client Commands_AESB Form Editor Set project variable Username_570.png]]
50
51 {{figureCaption}}
52 Variableneinstellungen vornehmen
53 {{/figureCaption}}
54 {{/figure}}
55
56 == Command //Set project variable //auswählen und editieren ==
57
58 1. Wählen Sie erneut das Command //Set project variable //aus.
59 1. Öffnen Sie den Befehl mit einem Doppelklick und öffnen Sie den Tab //Allgemein//.
60 1. Geben Sie unter der Beschreibung den Namen der Aktion ein, z.B. //Hier das AESB Benutzerkennwort setzen//. Nehmen Sie keine weiteren Änderungen an den anderen Einstellungen vor, diese sind nicht nötig.
61 1. Wechseln Sie in den Tab //Details//.
62 1. Optional: Legen Sie eine neue Variable unter den //Variableneinstellungen //an. Klicken Sie dafür auf das Icon neben den Listeneinträgen und es öffnet sich ein neues Fenster. Benennen Sie die neue Variable „PASSWORD“ und klicken Sie auf das Plus-Icon. Schließen Sie diesen Schritt mit dem //OK //ab.
63
64 {{aagon.infobox}}
65 Dieser Schritt ist optional, sollten Sie im Vorfeld diese Variable noch nicht angelegt haben.
66 {{/aagon.infobox}}
67
68 6. Wählen Sie die Option //Einzeiliger Text //aus, sollte dies noch nicht erfolgt sein. In dieser Zeile muss der Klartext später eingefügt werden, also das Passwort.
69 7. Beenden Sie Ihre Arbeiten an diesem Command und klicken Sie auf //OK//.
70
71 {{figure}}
72 (% style="text-align:center" %)
73 [[image:66_Use Case Client Commands_AESB Form Editor Set project variable Password_476.png]]
74
75 {{figureCaption}}
76 Variableneinstellungen festlegen
77 {{/figureCaption}}
78 {{/figure}}
79
80
81 == Command //Form Editor //öffnen und bearbeiten ==
82
83 {{aagon.warnungsbox}}
84 Das Client Command //Form Editor// ist äußerst komplex und sollte nur verwendet werden, wenn Sie über ausreichendes Wissen mit der Programmierung unter Delphi Skripten verfügen und auch wissen, wie die Nutzung einer [[IDE (Integrierte Entwicklungsumgebung)>>doc:65.ACMP-Solutions.Client Commands.Client Command erstellen.Client Commands neu hinzufügen.Client Command Editor.Commandlist.Dialogs.Der Form Editor.Die IDE.WebHome]] funktioniert.
85 {{/aagon.warnungsbox}}
86
87 Die Elemente des [[Form Editors>>doc:65.ACMP-Solutions.Client Commands.Client Command erstellen.Client Commands neu hinzufügen.Client Command Editor.Commandlist.Dialogs.Der Form Editor.WebHome]] können Sie entweder über die Code- oder Design-Ansicht bearbeiten. Der besseren Verständlichkeit wird im nachfolgenden Abschnitt nur vereinzelt auf die optische Design-Ansicht eingegangen, sondern mehr auf den Code. Hierdurch entfallen die Erklärungen zu den Eigenschaften und Events des Object Inspectors, die Sie [[hier>>doc:65.ACMP-Solutions.Client Commands.Client Command erstellen.Client Commands neu hinzufügen.Client Command Editor.Commandlist.Dialogs.Der Form Editor.WebHome||anchor="HObjectInspectorFormEditor"]] nachlesen können.
88
89 Mithilfe dieses Client Commands bauen Sie ein interaktives Formular, wo Sie einem Client ein ausgewähltes Client Command zuweisen können. Gehen Sie dafür wie folgt weiter vor:
90
91 1. Wählen Sie das Client Command //Form Editor //(//Dialogs //> //Form Editor//) aus.
92 1. Öffnen Sie den Befehl mit einem Doppelklick und öffnen Sie den Tab //Allgemein// und passen Sie optional die //Beschreibung der Aktion //an. In diesem Beispiel bleibt der Titel hier //Form Editor//.
93 1. Wechseln Sie in den Tab //Form bearbeiten//.
94 1. Klicken Sie unterhalb der Form Vorschau auf den Button //Form bearbeiten//. Es öffnet sich ein neues Fenster für die Arbeiten mit dem Form Editor in der Standardansicht, mit einigen benutzerdefinierten Feldern.
95
96 {{aagon.infobox}}
97 Hinweis: Lesen Sie [[hier>>doc:65.ACMP-Solutions.Client Commands.Client Command erstellen.Client Commands neu hinzufügen.Client Command Editor.Commandlist.Dialogs.Der Form Editor.WebHome||anchor="HObjectInspectorFormEditor"]] weitere Informationen zum Einsatz des Form Editors bzw. der IDE (Integrierte Entwicklerumgebung) nach.
98 {{/aagon.infobox}}
99
100 5. Wechseln Sie aus der Design- in die Code-Ansicht, indem Sie den unteren Tab klicken (siehe Abbildung). Die Ansicht verändert sich.
101
102 {{figure}}
103 (% style="text-align:center" %)
104 [[image:66_Use Case Client Commands_AESB Form Editor Standard_1191.png]]
105
106 {{figureCaption}}
107 Ansicht des Form Editors
108 {{/figureCaption}}
109 {{/figure}}
110
111 6. Wechseln Sie hier in den Tab //FormUnit//, sollten Sie sich noch nicht darin befinden. Sie sehen hier den Code vom oberen Custom Windows-Fenster aus der Design-Ansicht. Dieser Code muss nun für Ihre Zwecke angepasst werden.
112
113 {{figure}}
114 (% style="text-align:center" %)
115 [[image:66_Use Case Client Commands_AESB Form Editor Code Ansicht_592.png]]
116
117 {{figureCaption}}
118 Ansicht des Codes zum Custom Windows-Fenster
119 {{/figureCaption}}
120 {{/figure}}
121
122 == Code anpassen ==
123
124 Nachfolgend wird der Code in Sinnabschnitten unterteilt und jeweils erklärt. Fügen Sie die Zeilen immer in der hier dargestellten Reihenfolge ein, damit das Client Command richtig funktioniert. Hierbei wird die Form so ausgeführt, wie sie später angezeigt wird.
125
126 {{aagon.infobox}}
127 Sämtliche Angaben im Code, die nach einem doppelten Schrägstrich stehen, sind auskommentiert und dienen lediglich als spezifische Erklärung der nachfolgenden Zeilen. Sie sind nicht Teil der Ausführung.
128 {{/aagon.infobox}}
129
130
131 |(% style="width:859px" %)**Zeilenabschnitt**|(% style="width:505px" %)**Beschreibung**
132 |(% style="width:859px" %)**Zeile 1 - 13**|(% style="width:505px" %)
133 |(% style="width:859px" %){{code language="none"}}{$FORM TCustomACMPWindow, FormUnit.sfm}
134
135 uses
136 Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls,
137 StdCtrls, SysUtils, Buttons, AagonSQLQuery, AagonAESBV1,
138 ComCtrls;
139 var
140 LClients, LClientCommands, ResultMessages: TStringlist;
141 IResult, Protocol, ExchangeType, AErrorCode, ConnectionTimeout: Integer;
142 Server, Port, SClientID, SClientCommandID, MessageID, AAckMessages, AResult, Username,
143 Passwort, ConnectionString, VirtualRouter, RoutingKey, Tag, CallbackVirtualRouter, CallbackRoutingKey,
144 TargetConnectionVariable : string;
145 {{/code}}|(% style="width:505px" %)(((
146 In diesen Zeilen wird die Anzeige des Form Editors für den Benutzer festgelegt und beschrieben, womit die Anzeige befüllt wird und nach welchem Typ die Inhalte generiert werden (Datentyp: String, Zeile 12).
147
148 In den Zeilen werden Units hinzugefügt (//uses//, Zeilen 3 – 6) und Variablen (//var//, Zeilen 7 – 12) deklariert, die zu einem späteren Zeitpunkt befüllt werden können. Der jeweilige Variablentyp (z.B. TStringlist, Integer oder String) steht hinter den Variablennamen.
149
150
151 )))
152 |(% style="width:859px" %)**Zeile 14 - 21**|(% style="width:505px" %)
153 |(% style="width:859px" %){{code language="none"}}//
154 function EscapeValues(Value: String) : String;
155 begin
156 Value := '"'+StringReplace(Value,',','","')+'"';
157 Result := StringReplace(Value, '","","', ',');
158 end;
159
160 //{{/code}}|(% style="width:505px" %)Diese Funktion wird benötigt, um bestimmte Sonderzeichen in Strings zu verwenden. Einige Sonderzeichen im String haben eine besondere Bedeutung für das Programm: Wenn Sie diese Sonderzeichen anzeigen möchten, müssen Sie diese „escapen“. Beim Escapen wird dem anzuzeigenden Sonderzeichen dasselbe Zeichen vorangestellt oder aber ein bestimmtes anderes Zeichen, wie z.B. ein „\“.
161 |(% style="width:859px" %)**Zeile 22 - 45**|(% style="width:505px" %)
162 |(% style="width:859px" %){{code language="none"}}function SetAESBConfig;
163 begin
164 Protocol := 1; // HTTP (0) / HTTPS (1)
165 ConnectionTimeout:= 30; // Timeout in Sekunden
166 ExchangeType:= 1; // Direct (0) / Routing (1)
167 ResultMessages.Clear();
168 AAckMessages:= '';
169 AResult:= '';
170 AErrorCode:= 0;
171 IResult:= 0;
172 Server:= '127.0.0.1';
173 Port:= '3900';
174 Username:= GetVarContent('USERNAME');
175 Passwort:= GetVarContent('PASSWORD');
176 TargetConnectionVariable:= 'CONNECTION';
177 ConnectionString:= '';
178 MessageID:= '{43584358-4358-4358-4358-435843584358}'; //hier kann eine beliebige GUID verwendet werden
179 VirtualRouter:= 'VCMN';
180 RoutingKey:= '?.Aagon.Components.ACMPServer.*';
181 Tag:= 'ICQL';
182 CallbackVirtualRouter := '';
183 CallbackRoutingKey := '';
184 end;
185 {{/code}}|(% style="width:505px" %)(((
186 In diesem Abschnitt werden die Variablen für die AESB Service Funktion (//function SetAESBConfig//, Zeile 22) definiert und mit Werten befüllt. Die Funktion wird im späteren Verlauf benötigt (ab Zeile 142), die Sie aber bereits an dieser Stelle konfigurieren müssen.
187
188
189 Befüllen Sie die Zeilen der Funktion wie folgt:
190
191 Zeile 24: Tragen Sie hier den Typen des Protokolls ein. Der Wert 0 steht für eine HTTP Seite, die 1 für eine HTTPS Seite. Fügen Sie hier eine 1 ein, da es sich um eine verschlüsselte Anfrage handelt.
192
193 Zeile 25: Legen Sie eine Sekundenanzahl fest, wann die Anfrage an das AESB in ein Timeout läuft. Hier wurde der Standardwert „30 Sekunden“ angegeben.
194
195 Zeile 26: Der ExchangeType kann entweder über den Typen „Direct (0)“ oder „Routing (1)“ befüllt werden. Hier wird die letztere Option gewählt.
196
197 Zeile 27: ResultMessages.Clear() löscht die Stringliste.
198
199 Zeilen 28 – 29: Die beiden Variablen //AAckMessages //und //AResult //können leer bleiben. Tragen Sie dafür hinter dem Gleichheitszeichen '' ein.
200
201 Zeilen 30 – 31: Der //AErrorCode //und //IResult //werden jeweils mit dem Wert 0 befüllt.
202
203 Zeile 32: Tragen Sie hier den Namen oder die IP des AESB Servers ein, mit dem Sie sich verbinden wollen. In diesem Beispiel ist es '127.0.0.1'.
204
205 Zeile 33: Tragen Sie hier die Portnummer ein, die Sie für die Verbindung benötigen (hier: '3900').
206
207 Zeile 34: Hier wird die Funktion //GetVarContent// verwendet, die auf die Projektvariable ('USERNAME') verweist. Die Projektvariable muss außerhalb des Form Editors im Client Command selber angelegt und befüllt werden.
208
209 Zeile 35: Hier wird die Funktion //GetVarContent// verwendet, die auf die Projektvariable ('PASSWORD') verweist. Auch diese Projektvariable muss außerhalb des Form Editors im Client Command selber angelegt und befüllt werden.
210
211 Zeile 36: Die Variable TargetConnectionVariable muss mit dem Wert 'CONNECTION' befüllt werden. Das Protokoll setzt diesen Typen für diese Art der Verbindung voraus (Typ: Connection).
212
213 Zeile 37: Der Wert des ConnectionStrings bleibt leer (' ') und wird im späteren Verlauf mit Werten befüllt.
214
215 Zeile 38: Die MessageID ist eine GUID, die beliebig ausgetauscht und verwendet werden kann. Bei der Eingabe ist es jedoch wichtig, dass diese dem gleichen Eingabeschema folgt: Die Anzahl der Stellen muss gleichbleiben (jeweils 8-4-4-4-8 Ziffern).
216
217 Zeile 39: Für den VirtualRouter muss der Wert 'VCMN' eingegeben werden. Es handelt sich hierbei um einen virtuellen Abschnitt innerhalb des AESB, in dem sich der ACMP Server befindet. Da in diesem Beispiel mit dem ACMP kommuniziert wird, muss dieser Router angegeben werden.
218
219 Zeile 40: Der RoutingKey gibt an, wohin die eingegebenen Werte geschickt werden sollen. Demnach muss hier der ACMP Server eingetragen werden, der die Eingaben erhalten soll. In diesem Beispiel heißt er '?.Aagon.Components.ACMPServer.*'. Das Fragezeichen und das Sternchen stehen beide für eine Wildcard. Das Sternchen repräsentiert hierbei die ACMP Server-ID. Sollten Sie mehrere ACMP Server mit dem AESB verbunden haben, können Sie auch die ID eines Servers eintragen, um die Daten nur dorthin zu leiten.
220
221 Zeile 41: Die Eingabezeile //Tag// beschreibt die Art der Nachricht. Da hier das ICQL Protokoll verwendet wird, muss der einzutragende Wert 'ICQL' lauten.
222
223 Zeilen 42 – 43: Hier werden der Virtual Router (CallbackVirtualRouter, Zeile 42) und Routing Key (CallbackRoutingKey, Zeile 43) angezeigt. Es wird keine Rückantwort benötigt, daher reicht hinter dem Gleichheitszeichen in beiden Zeilen ein '' als leerer Wert.
224 )))
225 |(% style="width:859px" %)**Zeile 46 - 55**|(% style="width:505px" %)
226 |(% style="width:859px" %){{code language="none"}}function GetClientID : String;
227 var
228 Ltemp : TStringList;
229 begin
230 LTemp := TStringList.Create();
231 LTemp.CommaText := LClients.Strings[LBClients.ItemIndex];
232 Result := LTemp.Values['CLIENTID'];
233 LTemp.Free();
234 end
235 {{/code}}|(% style="width:505px" %)(((
236 In den Zeilen 46 – 50 wird die Funktion //GetClientID//, mit einem Rückgabewert des Typen String, beschrieben. Die Funktion ermittelt die Client-ID des in der Oberfläche ausgewählten Clients aus der Liste //LBClients//.
237
238 Zeile 46: Beginn der Funktion //GetClientID //mit einem String als Rückgabewert.
239
240 Zeilen 47 – 54: Der Wert //LClients.Strings //beinhaltet den Index des Clients, den Sie ausgewählt haben. Mit diesem Index wird in der Liste //LClients.Strings //der entsprechende Client ausgesucht und in eine temporäre Variable zwischengespeichert. Der Rückgabewert der Funktion (Zeile 52) wird auf den Wert „Client-ID“ aus der temporären Variable gesetzt und entspricht damit der Client-ID, die Sie als selektierten Agenten aus der Liste gewählt haben. Über die Zeile 53 wird der Arbeitsspeicher wieder freigegeben.
241 )))
242 |(% style="width:859px" %)**Zeile 56 - 65**|(% style="width:505px" %)
243 |(% style="width:859px" %){{code language="none"}}function GetClientCommandID : String;
244 var
245 Ltemp : TStringList;
246 begin
247 LTemp := TStringList.Create();
248 LTemp.CommaText := LClientCommands.Strings[LBClientCommands.ItemIndex];
249 Result := LTemp.Values['SCRIPTID'];
250 LTemp.Free();
251 end
252 {{/code}}|(% style="width:505px" %)(((
253 Die Zeilen 56 – 65 beschreiben die Funktion //GetClientCommandID//. Die Funktion ermittelt die Client Command-ID des in der Oberfläche ausgewählten Client Commands aus der Liste //LBClientCommands//.
254
255 Zeile 56: Beginn der Funktion //GetClientCommandID //mit einem String als Rückgabewert.
256
257 Zeilen 57 – 65: //LBClientCommands.ItemIndex //beinhaltet den Index des Client Commands, den Sie ausgewählt haben. Mit diesem Index wird in der Liste //LClientCommands.Strings //das entsprechende Client Command ausgesucht und in eine temporäre Variable zwischengespeichert. Der Rückgabewert der Funktion (Zeile 52) wird auf den Wert „Script-ID“ aus der temporären Variable gesetzt und entspricht damit der Client Command-ID, die Sie als selektiertes Client Command aus der Liste gewählt haben.
258
259 Der Arbeitsspeicher wird über die Zeile 63 freigegeben (//LTemp.Free()//).
260 )))
261 |(% style="width:859px" %)**Zeile 66 - 80**|(% style="width:505px" %)
262 |(% style="width:859px" %){{code language="none"}}function CreateMessageBody : String;
263 var
264 MessageBody : TStringList;
265 begin
266
267 MessageBody := TStringList.Create();
268 MessageBody.Add('<ICQL><ACMP><EnqueueClientCommand version="1">');
269 MessageBody.Add('<TEnqueueClientCommandRequest_V1 xmlns:xsi="http:~/~/www.w3.org/2001/XMLSchema-instance">');
270 MessageBody.Add('<ClientId>'+GetClientID+'</ClientId>');
271 MessageBody.Add('<ClientCommandId>'+GetClientCommandID+'</ClientCommandId>');
272 MessageBody.Add('</TEnqueueClientCommandRequest_V1></EnqueueClientCommand></ACMP></ICQL>');
273 Result := MessageBody.Text;
274 MessageBody.Free();
275 end {{/code}}|(% style="width:505px" %)(((
276 Die Zeilen 66 – 80 beschreiben die Funktion für das Erstellen der Nachricht, die an den SICS / AESB gesendet wird. In dem Abschnitt, wo der MessageBody festgelegt und befüllt wird, muss zunächst der Datentyp definiert werden. In Zeile 72 werden verschiedene Werte hinterlegt, die zwingend eingehalten werden müssen. ICQL steht für das Format, in dem das SICS die Anfrage erwartet, ebenso wie den Wert //ACMP//. //EnqueueClientCommand //legt fest, dass eine Funktion zum Einreihen eines Client Commands aufgerufen werden soll und zwar in der Version 1.
277
278 Zeilen 74 und 75 legen fest, dass die Anfrage die //Client ID //und die //GetClientCommandID //als Tag beinhalten müssen, damit der Empfänger (in diesem Fall der ACMP Server) weiß, welches Client Command er zu welchem Client schicken muss.
279
280 Der Rückgabewert (Zeile 77) enthält dann die komplette Nachricht. Danach folgt eine Freigabe des Arbeitsspeichers über die Zeile 78.
281 )))
282 |(% style="width:859px" %)**Zeile 81 - 109**|(% style="width:505px" %)
283 |(% style="width:859px" %){{code language="none"}}procedure GetClients;
284 var
285 LSQL, LTemp : TStringList;
286 I : Integer;
287 begin
288 LSQL := TStringList.Create();
289 LTemp := TStringList.Create();
290
291 // SQLStatement zum Ermitteln der Clients
292 LSQL.Add('SELECT COMPUTERNAME, CLIENTID');
293 LSQL.Add('FROM CLT_CLIENTS');
294 LSQL.Add('WHERE ismanaged = 1');
295 LSQL.Add('ORDER BY COMPUTERNAME');
296
297 // Leeren der Listbox der Clients
298 LBClients.Clear();
299 LClients.Clear;
300 // Ausführen des Statements zum Beziehen der Clients aus der DB
301 SQLQuery(LSQL.Text,'','',LClients,true,30);
302
303 for i := 0 to (LClients.Count-1) do
304 begin
305 LTemp.Commatext := EscapeValues(LClients.Strings[i]);
306 LBClients.Items.Add(LTemp.Values['COMPUTERNAME']);
307 end
308 LSQL.Free();
309 LTemp.Free();
310 end;
311 {{/code}}|(% style="width:505px" %)(((
312 Die Zeilen 81 – 109 (//procedure GetClients//) holen die Agenten aus der Datenbank und speichern diese in die linke Box, die direkt beim Start des Fensters mit den Einträgen befüllt wird. Hierfür werden zunächst zwei Listen definiert und anschließend erzeugt (86 und 87). Anschließend wird die SQL Abfrage/ das SQL Statement zusammengebaut und mit Werten befüllt, womit die Ermittlung der Clients ermöglicht wird. Es wird nur der Computername und die Client-ID aus der Tabelle //CLT_Clients //geholt. Mit der Bedingung //ismanaged=1 //wird sichergestellt, dass es sich nur um gemangte Agenten handelt. Die Liste, die vom SQL Server zurückgeliefert wird, wird nach dem Computernamen sortiert (89 – 94). Die Listbox wird vor dem Befüllen einmal geleert, um zu verhindern, dass noch Einträge vorhanden sind (96 und 97).
313
314
315 Die Funktion// SQL Query// wendet das SQL Statement an und schreibt alle Clients in die globale Stringlist (//LClients//) (Zeile 99). Die Zeilen 101 – 107 befüllen die Oberfläche der Listbox, die Sie als Benutzer angezeigt bekommen. Die Listbox wird mit den Computernamen befüllt, die zuvor aus der SQL Abfrage geholt wurden. Die letzten beiden Zeilen (106 und 107) geben die zuvor erstellten Listen jeweils wieder frei.
316 )))
317 |(% style="width:859px" %)**Zeile 110 - 141**|(% style="width:505px" %)
318 |(% style="width:859px" %){{code language="none"}}procedure GetClientCommands;
319 var
320 LSQL, LTemp : TStringList;
321 I : Integer;
322 begin
323
324 LSQL := TStringList.Create();
325 LTemp := TStringList.Create();
326 LSQL.Add('DECLARE @Search nvarchar(200) = ' + QuotedStr(EDCCSearch.Text) + ';')
327 LSQL.Add('SELECT DESCRIPTION, SCRIPTID');
328 LSQL.Add('FROM SYS_SCRIPTS');
329 LSQL.Add('WHERE HASCLIENTSCRIPT = 1');
330 LSQL.Add('AND State = 7');
331 LSQL.Add('AND DESCRIPTION LIKE @Search');
332 LSQL.Add('ORDER BY DESCRIPTION');
333
334 // Leeren der Listbox der ClientCommands
335 LBClientCommands.Clear();
336 LClientCommands.Clear();
337 // Ausführen des Statements zum Beziehen der ClientCommands aus der DB
338 SQLQueryEx(LSQL.Text,'','',LClientCommands,true,emOpen,30);
339
340 for I := 0 to (LClientCommands.Count-1) do
341 begin
342 LTemp.Commatext := EscapeValues(LClientCommands.Strings[i]);
343 LBClientCommands.Items.Add(LTemp.Values['DESCRIPTION']);
344 end
345
346 LSQL.Free();
347 LTemp.Free();
348 end;
349 {{/code}}|(% style="width:505px" %)(((
350 Mit diesen Zeilen (110 – 141) wird die rechte Box mit den Client Command Einträgen befüllt, indem sie aus der SQL Datenbank geladen und dort eingefügt werden. Es werden zunächst zwei Listen definiert (116 und 117). Zum Ermitteln der Client Commands wird eine SQL-Abfrage in den Zeilen 119 – 124 erstellt. Zeile 118 verwendet das Suchfeld der Oberfläche, um nur Client Commands mit diesem Namen aus der Datenbank zu holen. Die Eingabe der Wildcard „%“ holt alle Client Commands aus der Datenbank, die Eingabe „Test_%“ holt lediglich alle Client Commands die mit „Test_“ im Namen beginnen.  (//LSQL.Add('DECLARE @Search nvarchar(200) = ' + QuotedStr(EDCCSearch.Text) + ';')//).
351
352 Über die Zeilen 127 und 128 wird die Listbox und die globale Liste der Client Commands geleert. Es folgt die Ausführung des Statements über die SQL Query, wobei die geholten Client Commands in die globale Stringlist (//LClientCommands//) geschrieben werden. Die Zeilen 132 – 136 befüllen die Oberfläche der Listbox mit der Description (Name) des Client Commands, die aus der SQL Abfrage zuvor geholt wurden. Die Zeilen 138 und 139 geben die Funktionen wieder jeweils frei.
353 )))
354 |(% style="width:859px" %)**Zeile 142 - 151**|(% style="width:505px" %)
355 |(% style="width:859px" %){{code language="none"}}procedure FormActivate;
356 begin
357 LClients := TStringList.Create();
358 LClientCommands := TStringList.Create();
359
360 ResultMessages := TStringList.Create();
361 GetClients;
362 SetAESBConfig;
363 end;
364 {{/code}}|(% style="width:505px" %)(((
365 //Procdure FormActivate //(Zeilen 142 – 151) wird aufgerufen, wenn das Fenster erstellt wird. Die globalen Listen //LClients// und //LClientCommands// werden als erstes erzeugt (144 und 145). Die Methode //GetClients //holt alle Clients aus der Datenbank und zeigt sie in der Oberfläche an (siehe obere Funktion) (148).// //Die Funktion //SetAESBConfig //wird in Zeile 149 aufgerufen und setzt alle Variablen, die zuvor von Ihnen eingestellt wurden und die notwendig sind, um mit dem AESB zu kommunizieren (siehe Funktion oben).
366 )))
367 |(% style="width:859px" %)**Zeile 152 - 160**|(% style="width:505px" %)
368 |(% style="width:859px" %){{code language="none"}}procedure OkButtonClick(Sender: TObject);
369 begin
370 LClients.Free();
371 LClientCommands.Free();
372
373 ResultMessages.Free();
374 CloseForm(0);
375 end;
376 {{/code}}|(% style="width:505px" %)(((
377 Die Funktion in den Zeilen 152 – 160 wird aufgerufen, wenn der OK Button gedrückt wird. Dabei werden alle Listen geleert, damit keine Einträge mehr in //LClients //oder //LClientCommands //stehen. Zeile 158 //CloseForm(0) //schließt die Form mit dem Parameter 0.
378
379 {{aagon.infobox}}
380 Als Parameter in der Klammer können Sie jede beliebige Ganzzahl reinschreiben. Standardmäßig bedeutet eine -1, dass dieser Baustein fehlgeschlagen ist. Diese Zahl (-1) lässt sich beim Start des Form Editors einstellen. Wird die Funktion CloseForm(-1) dann aufgerufen, wird dieser Baustein das Client Command fehlschlagen lassen und es werden nach diesem Baustein keine weiteren Commands mehr ausgeführt.
381 {{/aagon.infobox}}
382 )))
383 |(% style="width:859px" %)**Zeile 161 - 169**|(% style="width:505px" %)
384 |(% style="width:859px" %){{code language="none"}}procedure CancelButtonClick(Sender: TObject);
385 begin
386 LClients.Free();
387 LClientCommands.Free();
388
389 ResultMessages.Free();
390 CloseForm(1);
391 end;
392 {{/code}}|(% style="width:505px" %)(((
393 Die Zeilen 161 – 169 werden aufgerufen, wenn der Abbrechen Button gedrückt wird. Hierbei werden wie bereits im vorherigen Abschnitt alle Listen geleert und die //Closeform// (Zeile 167) mit dem Parameter 1 befüllt, um eine bessere Unterscheidung zwischen dem OK und Abbrechen Button aufzuzeigen, wobei dieser Wert keinen Fehler darstellt. Dieser Parameter kann im Client Command als Rückgabewert der Form genutzt werden, um zu unterscheiden, ob der OK oder der Abbrechen Button gedrückt wurde.
394 )))
395 |(% style="width:859px" %)**Zeile 170 - 176**|(% style="width:505px" %)
396 |(% style="width:859px" %){{code language="none"}}procedure CBSureClick(Sender: TObject);
397 begin
398 if ((CBSure.Checked) AND (LBClients.ItemIndex > -1 ) AND (LBClientCommands.ItemIndex > -1 ))
399 then BtnSend.Enabled := True;
400 Else BtnSend.Enabled := False;
401 end;
402 {{/code}}|(% style="width:505px" %)(((
403 Dieser Zeilenabschnitt wird aufgerufen, wenn die Checkbox //CBSure //angeklickt wird („Ich bin sicher“), die der Benutzer vor dem Abschicken eines Commands aktivieren muss. Der Prozess //procedure CBSureClick(Sender:TOBject) //(ab Zeile 170) stellt sicher, dass die nachfolgenden Bedingungen erfüllt sind (171 – 175) und dadurch der Button //Command Senden //aktiviert wird. Die Bedingung lautet:
404
405 Wenn //CBSure// (true) (Checkbox angehakt) ist, ein Client aus der linken und ein Client Command aus der rechten Box ausgewählt wurden (ItemIndex muss größer als -1 sein; es muss also ein ausgewähltes Element selektiert sein), dann wird der Button //Command Senden //aktiviert (//BtnSend.Enabled :=True//). Andernfalls wird der Button beim Else deaktiviert.
406 )))
407 |(% style="width:859px" %)**Zeile 177 - 194**|(% style="width:505px" %)
408 |(% style="width:859px" %){{code language="none"}}procedure BtnSendClick(Sender: TObject);
409 var
410 AESBMessage : String;
411 begin
412 AESBMessage := CreateMessageBody;
413 AddSICSConnectionV1(Protocol,Server,Port,Username,
414 Passwort,ConnectionTimeout,TargetConnectionVariable,false);
415 ConnectionString := GetVarContent('CONNECTION');
416 IResult := SICSPublishV1(ConnectionString, MessageID, VirtualRouter, RoutingKey, ExchangeType, Tag,
417 AESBMessage, CallbackVirtualRouter, CallbackRoutingKey, ResultMessages, AAckMessages, AResult, AErrorCode);
418 if (IResult = 0) then
419 begin
420 ShowMessage('Command has been send');
421 CBSure.Checked := false;
422 BtnSend.Enabled := false;
423 end;
424 Else Showmessage('An Error has occured: '+InttoStr(IResult));
425 end;
426 {{/code}}|(% style="width:505px" %)(((
427 Die Funktion //procedure BtnSendClick(Sender: TObject)// wird in den nachfolgenden Zeilen definiert und danach ausgeführt, sobald der Benutzer auf den Button klickt. Dabei wird die Variable (AESBMessage) deklariert (Zeile 179), dessen Datentyp ein String ist.
428
429 Anschließend wird die Funktion //CreateMessageBody //aufgerufen. In dieser Funktion wird der MessageBody einmal komplett zusammengebaut und als Rückgabewert zurückgeliefert. Dieser Rückgabewert wird wiederum in die //AESBMessage //Variable eingefügt (Zeile 181). Danach wird die SICS Connection hergestellt, die aus den verschiedenen Parametern und der Funktion //AddSICSConnectionV1 //besteht. In der Zeile 183 wird die Variable //ConnectionString //mit der Funktion //GetVarContent //befüllt. Die Funktion holt sich den Wert aus der Client Command Variable mit dem Namen (Parameter der Funktion) „Connection“. In Zeile 184 geht es mit der Variable //IResult //weiter, wo das Ergebnis der Funktion als //SICSPublishV1 //gespeichert wird. Die diversen Parameter werden an das AESB gesendet. Es folgt eine if.. then-Klausel: Das Ergebnis (IResult) der Funktion wird überprüft, ob das Ergebnis gleich 0 ist und es somit keine Fehler gab. Die Funktion //ShowMessage// wird aufgerufen, wodurch sich ein Dialogfenster mit dem Text „Command has been send“ öffnet (Zeile 188). In den beiden darauffolgenden Zeilen werden die Eigenschaften „Checked“ für die Checkbox und „Enabled“ für den Button auf //False //gesetzt. Somit haben die Objekte wieder den Ausgangszustand wiederhergestellt. Sollte ein Fehler aufgetreten sein, wird der Else-Teil ausgeführt (Zeile 192) und ein Dialog „An Error has occured“ angezeigt, sowie das Ergebnis von IResult (der Fehlercode).
430 )))
431
432 7. Wenn Sie alle relevanten Angaben in dem Code eingefügt oder angepasst haben, können Sie die Form über die Schnellwahlleiste mit dem Button //Start //[[image:image-20240205143129-1.png]] (F9) durchlaufen lassen. Beachten Sie hierzu, dass es sich hier nicht nur um einen Test handelt, mit dem Sie auf mögliche Syntax-, Rechtschreib- oder Logikfehler überprüfen können, sondern auch schon Client Commands zu einem Agenten absenden können. In der nachfolgenden Abbildung sehen Sie die fertige Form, so wie Sie bei Ihnen angezeigt werden kann.
433
434 {{figure}}
435 (% style="text-align:center" %)
436 [[image:66_Client Command_Use Case Form Editor Design Ansicht_832.png]]
437
438 {{figureCaption}}
439 Fertiges Client Command in dem Custom Window
440 {{/figureCaption}}
441 {{/figure}}
442
443 8. Schließen Sie die geöffneten Fenster (Custom Window und den Form Editor). Sie kommen wieder zur Benutzeroberfläche des Form Editors und dessen Vorschau zurück.
444
445 9. Überprüfen Sie unter //Skript Rückgabewert //den eingetragenen Wert. Hier sollte die Ganzzahl "-1" stehen.
446
447 {{figure}}
448 (% style="text-align:center" %)
449 [[image:66_Use Case Client Commands_AESB Form Editor fertig_510.png]]
450
451 {{figureCaption}}
452 Form Editor Vorschau
453 {{/figureCaption}}
454 {{/figure}}
455
456 10. Klicken Sie anschließend auf //OK//.
457
458 ~11. Speichern Sie das fertige Client Command ab und schließen Sie den Editor.
459
460 {{figure}}
461 (% style="text-align:center" %)
462 [[image:66_Use Case Client Commands_AESB fertiges Script_1487.png]]
463
464 {{figureCaption}}
465 Client Command-Editor: Client Command per Form Editor via AESB statisch an einen Client senden
466 {{/figureCaption}}
467 {{/figure}}
468
469 == Client Command-Phasen durchlaufen lassen ==
470
471 Ehe das Client Command verwendet werden kann, muss es noch abschließend die Phasen [[Testen>>doc:ACMP.65.ACMP-Solutions.Client Commands.Client Command testen.WebHome]], [[Synchronisieren>>doc:ACMP.65.ACMP-Solutions.Client Commands.Client Command synchronisieren.WebHome]], [[Freigeben>>doc:ACMP.65.ACMP-Solutions.Client Commands.Client Command freigeben.WebHome]] und [[Ausführen>>doc:ACMP.65.ACMP-Solutions.Client Commands.Client Command ausführen.WebHome]] durchlaufen. Danach ist es möglich die Client Commands mit Hilfe des [[Form Editors>>doc:65.ACMP-Solutions.Client Commands.Client Command erstellen.Client Commands neu hinzufügen.Client Command Editor.Commandlist.Dialogs.Der Form Editor.WebHome]] über das AESB statisch an einen Client zu senden.
© Aagon GmbH 2025
Besuchen Sie unsere Aagon-Community