Zuletzt geändert von Sabrina V. am 2024/08/22 07:29

Zeige letzte Bearbeiter
1 {{aagon.priorisierung}}
2 160
3 {{/aagon.priorisierung}}
4
5
6 {{aagon.floatingbox/}}
7
8 = Ausgangslage =
9
10 In diesem Anwendungsfall wird Ihnen anhand einer Schritt-für-Schritt Anleitung aufgezeigt, wie Sie mithilfe eines Client Commands den [[Form Editor>>doc:ACMP.66.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.
11
12 Zur besseren Verständlichkeit wird der Inhalt des //Form Editors //größtenteils in der Code-Ansicht erläutert.
13
14 {{figure}}
15 [[image:66_Use Case Client Commands_AESB Code Ausschnitt_906.png||data-xwiki-image-style-alignment="center"]]
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 [[image:66_Use Case Client Commands_AESB Form Editor Set project variable Username_570.png||data-xwiki-image-style-alignment="center"]]
49
50 {{figureCaption}}
51 Variableneinstellungen vornehmen
52 {{/figureCaption}}
53 {{/figure}}
54
55 == Command //Set project variable //auswählen und editieren ==
56
57 1. Wählen Sie erneut das Command //Set project variable //aus.
58 1. Öffnen Sie den Befehl mit einem Doppelklick und öffnen Sie den Tab //Allgemein//.
59 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.
60 1. Wechseln Sie in den Tab //Details//.
61 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.
62
63 {{aagon.infobox}}
64 Dieser Schritt ist optional, sollten Sie im Vorfeld diese Variable noch nicht angelegt haben.
65 {{/aagon.infobox}}
66
67 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.
68 7. Beenden Sie Ihre Arbeiten an diesem Command und klicken Sie auf //OK//.
69
70 {{figure}}
71 [[image:66_Use Case Client Commands_AESB Form Editor Set project variable Password_476.png||data-xwiki-image-style-alignment="center"]]
72
73 {{figureCaption}}
74 Variableneinstellungen festlegen
75 {{/figureCaption}}
76 {{/figure}}
77
78
79 == Command //Form Editor //öffnen und bearbeiten ==
80
81 {{aagon.warnungsbox}}
82 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:ACMP.66.ACMP-Solutions.Client Commands.Client Command erstellen.Client Commands neu hinzufügen.Client Command Editor.Commandlist.Dialogs.Der Form Editor.Die IDE.WebHome]] funktioniert.
83 {{/aagon.warnungsbox}}
84
85 Die Elemente des [[Form Editors>>doc:ACMP.66.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:ACMP.66.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.
86
87 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:
88
89 1. Wählen Sie das Client Command //Form Editor //(//Dialogs //> //Form Editor//) aus.
90 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//.
91 1. Wechseln Sie in den Tab //Form bearbeiten//.
92 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.
93
94 {{aagon.infobox}}
95 Hinweis: Lesen Sie [[hier>>doc:ACMP.66.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.
96 {{/aagon.infobox}}
97
98 5. Wechseln Sie aus der Design- in die Code-Ansicht, indem Sie den unteren Tab klicken (siehe Abbildung). Die Ansicht verändert sich.
99
100 {{figure}}
101 [[image:66_Use Case Client Commands_AESB Form Editor Standard_1191.png||data-xwiki-image-style-alignment="center"]]
102
103 {{figureCaption}}
104 Ansicht des Form Editors
105 {{/figureCaption}}
106 {{/figure}}
107
108 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.
109
110 {{figure}}
111 [[image:66_Use Case Client Commands_AESB Form Editor Code Ansicht_592.png||data-xwiki-image-style-alignment="center"]]
112
113 {{figureCaption}}
114 Ansicht des Codes zum Custom Windows-Fenster
115 {{/figureCaption}}
116 {{/figure}}
117
118 == Code anpassen ==
119
120 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.
121
122 {{aagon.infobox}}
123 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.
124 {{/aagon.infobox}}
125
126
127 |(% style="width:859px" %)**Zeilenabschnitt**|(% style="width:505px" %)**Beschreibung**
128 |(% style="width:859px" %)**Zeile 1 - 13**|(% style="width:505px" %)
129 |(% style="width:859px" %){{code language="none"}}{$FORM TCustomACMPWindow, FormUnit.sfm}
130
131 uses
132 Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls,
133 StdCtrls, SysUtils, Buttons, AagonSQLQuery, AagonAESBV1,
134 ComCtrls;
135 var
136 LClients, LClientCommands, ResultMessages: TStringlist;
137 IResult, Protocol, ExchangeType, AErrorCode, ConnectionTimeout: Integer;
138 Server, Port, SClientID, SClientCommandID, MessageID, AAckMessages, AResult, Username,
139 Passwort, ConnectionString, VirtualRouter, RoutingKey, Tag, CallbackVirtualRouter, CallbackRoutingKey,
140 TargetConnectionVariable : string;
141 {{/code}}|(% style="width:505px" %)(((
142 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).
143
144 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.
145
146
147 )))
148 |(% style="width:859px" %)**Zeile 14 - 21**|(% style="width:505px" %)
149 |(% style="width:859px" %){{code language="none"}}//
150 function EscapeValues(Value: String) : String;
151 begin
152 Value := '"'+StringReplace(Value,',','","')+'"';
153 Result := StringReplace(Value, '","","', ',');
154 end;
155
156 //{{/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 „\“.
157 |(% style="width:859px" %)**Zeile 22 - 45**|(% style="width:505px" %)
158 |(% style="width:859px" %){{code language="none"}}function SetAESBConfig;
159 begin
160 Protocol := 1; // HTTP (0) / HTTPS (1)
161 ConnectionTimeout:= 30; // Timeout in Sekunden
162 ExchangeType:= 1; // Direct (0) / Routing (1)
163 ResultMessages.Clear();
164 AAckMessages:= '';
165 AResult:= '';
166 AErrorCode:= 0;
167 IResult:= 0;
168 Server:= '127.0.0.1';
169 Port:= '3900';
170 Username:= GetVarContent('USERNAME');
171 Passwort:= GetVarContent('PASSWORD');
172 TargetConnectionVariable:= 'CONNECTION';
173 ConnectionString:= '';
174 MessageID:= '{43584358-4358-4358-4358-435843584358}'; //hier kann eine beliebige GUID verwendet werden
175 VirtualRouter:= 'VCMN';
176 RoutingKey:= '?.Aagon.Components.ACMPServer.*';
177 Tag:= 'ICQL';
178 CallbackVirtualRouter := '';
179 CallbackRoutingKey := '';
180 end;
181 {{/code}}|(% style="width:505px" %)(((
182 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.
183
184
185 Befüllen Sie die Zeilen der Funktion wie folgt:
186
187 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.
188
189 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.
190
191 Zeile 26: Der ExchangeType kann entweder über den Typen „Direct (0)“ oder „Routing (1)“ befüllt werden. Hier wird die letztere Option gewählt.
192
193 Zeile 27: ResultMessages.Clear() löscht die Stringliste.
194
195 Zeilen 28 – 29: Die beiden Variablen //AAckMessages //und //AResult //können leer bleiben. Tragen Sie dafür hinter dem Gleichheitszeichen '' ein.
196
197 Zeilen 30 – 31: Der //AErrorCode //und //IResult //werden jeweils mit dem Wert 0 befüllt.
198
199 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'.
200
201 Zeile 33: Tragen Sie hier die Portnummer ein, die Sie für die Verbindung benötigen (hier: '3900').
202
203 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.
204
205 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.
206
207 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).
208
209 Zeile 37: Der Wert des ConnectionStrings bleibt leer (' ') und wird im späteren Verlauf mit Werten befüllt.
210
211 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).
212
213 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.
214
215 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.
216
217 Zeile 41: Die Eingabezeile //Tag// beschreibt die Art der Nachricht. Da hier das ICQL Protokoll verwendet wird, muss der einzutragende Wert 'ICQL' lauten.
218
219 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.
220 )))
221 |(% style="width:859px" %)**Zeile 46 - 55**|(% style="width:505px" %)
222 |(% style="width:859px" %){{code language="none"}}function GetClientID : String;
223 var
224 Ltemp : TStringList;
225 begin
226 LTemp := TStringList.Create();
227 LTemp.CommaText := LClients.Strings[LBClients.ItemIndex];
228 Result := LTemp.Values['CLIENTID'];
229 LTemp.Free();
230 end
231 {{/code}}|(% style="width:505px" %)(((
232 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//.
233
234 Zeile 46: Beginn der Funktion //GetClientID //mit einem String als Rückgabewert.
235
236 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.
237 )))
238 |(% style="width:859px" %)**Zeile 56 - 65**|(% style="width:505px" %)
239 |(% style="width:859px" %){{code language="none"}}function GetClientCommandID : String;
240 var
241 Ltemp : TStringList;
242 begin
243 LTemp := TStringList.Create();
244 LTemp.CommaText := LClientCommands.Strings[LBClientCommands.ItemIndex];
245 Result := LTemp.Values['SCRIPTID'];
246 LTemp.Free();
247 end
248 {{/code}}|(% style="width:505px" %)(((
249 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//.
250
251 Zeile 56: Beginn der Funktion //GetClientCommandID //mit einem String als Rückgabewert.
252
253 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.
254
255 Der Arbeitsspeicher wird über die Zeile 63 freigegeben (//LTemp.Free()//).
256 )))
257 |(% style="width:859px" %)**Zeile 66 - 80**|(% style="width:505px" %)
258 |(% style="width:859px" %){{code language="none"}}function CreateMessageBody : String;
259 var
260 MessageBody : TStringList;
261 begin
262
263 MessageBody := TStringList.Create();
264 MessageBody.Add('<ICQL><ACMP><EnqueueClientCommand version="1">');
265 MessageBody.Add('<TEnqueueClientCommandRequest_V1 xmlns:xsi="http:~/~/www.w3.org/2001/XMLSchema-instance">');
266 MessageBody.Add('<ClientId>'+GetClientID+'</ClientId>');
267 MessageBody.Add('<ClientCommandId>'+GetClientCommandID+'</ClientCommandId>');
268 MessageBody.Add('</TEnqueueClientCommandRequest_V1></EnqueueClientCommand></ACMP></ICQL>');
269 Result := MessageBody.Text;
270 MessageBody.Free();
271 end {{/code}}|(% style="width:505px" %)(((
272 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.
273
274 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.
275
276 Der Rückgabewert (Zeile 77) enthält dann die komplette Nachricht. Danach folgt eine Freigabe des Arbeitsspeichers über die Zeile 78.
277 )))
278 |(% style="width:859px" %)**Zeile 81 - 109**|(% style="width:505px" %)
279 |(% style="width:859px" %){{code language="none"}}procedure GetClients;
280 var
281 LSQL, LTemp : TStringList;
282 I : Integer;
283 begin
284 LSQL := TStringList.Create();
285 LTemp := TStringList.Create();
286
287 // SQLStatement zum Ermitteln der Clients
288 LSQL.Add('SELECT COMPUTERNAME, CLIENTID');
289 LSQL.Add('FROM CLT_CLIENTS');
290 LSQL.Add('WHERE ismanaged = 1');
291 LSQL.Add('ORDER BY COMPUTERNAME');
292
293 // Leeren der Listbox der Clients
294 LBClients.Clear();
295 LClients.Clear;
296 // Ausführen des Statements zum Beziehen der Clients aus der DB
297 SQLQuery(LSQL.Text,'','',LClients,true,30);
298
299 for i := 0 to (LClients.Count-1) do
300 begin
301 LTemp.Commatext := EscapeValues(LClients.Strings[i]);
302 LBClients.Items.Add(LTemp.Values['COMPUTERNAME']);
303 end
304 LSQL.Free();
305 LTemp.Free();
306 end;
307 {{/code}}|(% style="width:505px" %)(((
308 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).
309
310
311 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.
312 )))
313 |(% style="width:859px" %)**Zeile 110 - 141**|(% style="width:505px" %)
314 |(% style="width:859px" %){{code language="none"}}procedure GetClientCommands;
315 var
316 LSQL, LTemp : TStringList;
317 I : Integer;
318 begin
319
320 LSQL := TStringList.Create();
321 LTemp := TStringList.Create();
322 LSQL.Add('DECLARE @Search nvarchar(200) = ' + QuotedStr(EDCCSearch.Text) + ';')
323 LSQL.Add('SELECT DESCRIPTION, SCRIPTID');
324 LSQL.Add('FROM SYS_SCRIPTS');
325 LSQL.Add('WHERE HASCLIENTSCRIPT = 1');
326 LSQL.Add('AND State = 7');
327 LSQL.Add('AND DESCRIPTION LIKE @Search');
328 LSQL.Add('ORDER BY DESCRIPTION');
329
330 // Leeren der Listbox der ClientCommands
331 LBClientCommands.Clear();
332 LClientCommands.Clear();
333 // Ausführen des Statements zum Beziehen der ClientCommands aus der DB
334 SQLQueryEx(LSQL.Text,'','',LClientCommands,true,emOpen,30);
335
336 for I := 0 to (LClientCommands.Count-1) do
337 begin
338 LTemp.Commatext := EscapeValues(LClientCommands.Strings[i]);
339 LBClientCommands.Items.Add(LTemp.Values['DESCRIPTION']);
340 end
341
342 LSQL.Free();
343 LTemp.Free();
344 end;
345 {{/code}}|(% style="width:505px" %)(((
346 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) + ';')//).
347
348 Ü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.
349 )))
350 |(% style="width:859px" %)**Zeile 142 - 151**|(% style="width:505px" %)
351 |(% style="width:859px" %){{code language="none"}}procedure FormActivate;
352 begin
353 LClients := TStringList.Create();
354 LClientCommands := TStringList.Create();
355
356 ResultMessages := TStringList.Create();
357 GetClients;
358 SetAESBConfig;
359 end;
360 {{/code}}|(% style="width:505px" %)(((
361 //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).
362 )))
363 |(% style="width:859px" %)**Zeile 152 - 160**|(% style="width:505px" %)
364 |(% style="width:859px" %){{code language="none"}}procedure OkButtonClick(Sender: TObject);
365 begin
366 LClients.Free();
367 LClientCommands.Free();
368
369 ResultMessages.Free();
370 CloseForm(0);
371 end;
372 {{/code}}|(% style="width:505px" %)(((
373 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.
374
375 {{aagon.infobox}}
376 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.
377 {{/aagon.infobox}}
378 )))
379 |(% style="width:859px" %)**Zeile 161 - 169**|(% style="width:505px" %)
380 |(% style="width:859px" %){{code language="none"}}procedure CancelButtonClick(Sender: TObject);
381 begin
382 LClients.Free();
383 LClientCommands.Free();
384
385 ResultMessages.Free();
386 CloseForm(1);
387 end;
388 {{/code}}|(% style="width:505px" %)(((
389 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.
390 )))
391 |(% style="width:859px" %)**Zeile 170 - 176**|(% style="width:505px" %)
392 |(% style="width:859px" %){{code language="none"}}procedure CBSureClick(Sender: TObject);
393 begin
394 if ((CBSure.Checked) AND (LBClients.ItemIndex > -1 ) AND (LBClientCommands.ItemIndex > -1 ))
395 then BtnSend.Enabled := True;
396 Else BtnSend.Enabled := False;
397 end;
398 {{/code}}|(% style="width:505px" %)(((
399 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:
400
401 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.
402 )))
403 |(% style="width:859px" %)**Zeile 177 - 194**|(% style="width:505px" %)
404 |(% style="width:859px" %){{code language="none"}}procedure BtnSendClick(Sender: TObject);
405 var
406 AESBMessage : String;
407 begin
408 AESBMessage := CreateMessageBody;
409 AddSICSConnectionV1(Protocol,Server,Port,Username,
410 Passwort,ConnectionTimeout,TargetConnectionVariable,false);
411 ConnectionString := GetVarContent('CONNECTION');
412 IResult := SICSPublishV1(ConnectionString, MessageID, VirtualRouter, RoutingKey, ExchangeType, Tag,
413 AESBMessage, CallbackVirtualRouter, CallbackRoutingKey, ResultMessages, AAckMessages, AResult, AErrorCode);
414 if (IResult = 0) then
415 begin
416 ShowMessage('Command has been send');
417 CBSure.Checked := false;
418 BtnSend.Enabled := false;
419 end;
420 Else Showmessage('An Error has occured: '+InttoStr(IResult));
421 end;
422 {{/code}}|(% style="width:505px" %)(((
423 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.
424
425 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).
426 )))
427
428 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.
429
430 {{figure}}
431 [[image:66_Client Command_Use Case Form Editor Design Ansicht_832.png||data-xwiki-image-style-alignment="center"]]
432
433 {{figureCaption}}
434 Fertiges Client Command in dem Custom Window
435 {{/figureCaption}}
436 {{/figure}}
437
438 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.
439
440 9. Überprüfen Sie unter //Skript Rückgabewert //den eingetragenen Wert. Hier sollte die Ganzzahl "-1" stehen.
441
442 {{figure}}
443 [[image:66_Use Case Client Commands_AESB Form Editor fertig_510.png||data-xwiki-image-style-alignment="center"]]
444
445 {{figureCaption}}
446 Form Editor Vorschau
447 {{/figureCaption}}
448 {{/figure}}
449
450 10. Klicken Sie anschließend auf //OK//.
451
452 ~11. Speichern Sie das fertige Client Command ab und schließen Sie den Editor.
453
454 {{figure}}
455 [[image:66_Use Case Client Commands_AESB fertiges Script_1487.png||data-xwiki-image-style-alignment="center"]]
456
457 {{figureCaption}}
458 Client Command-Editor: Client Command per Form Editor via AESB statisch an einen Client senden
459 {{/figureCaption}}
460 {{/figure}}
461
462 == Client Command-Phasen durchlaufen lassen ==
463
464 Ehe das Client Command verwendet werden kann, muss es noch abschließend die Phasen [[Testen>>doc:ACMP.66.ACMP-Solutions.Client Commands.Client Command testen.WebHome]], [[Synchronisieren>>doc:ACMP.66.ACMP-Solutions.Client Commands.Client Command synchronisieren.WebHome]], [[Freigeben>>doc:ACMP.66.ACMP-Solutions.Client Commands.Client Command freigeben.WebHome]] und [[Ausführen>>doc:ACMP.66.ACMP-Solutions.Client Commands.Client Command ausführen.WebHome]] durchlaufen. Danach ist es möglich die Client Commands mit Hilfe des [[Form Editors>>doc:ACMP.66.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 neue Aagon-Community