Zuletzt geändert von Steffi F am 2025/05/05 09:56

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