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

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