Last modified by Jannis Klein on 2024/08/13 08:28

Show last authors
1 {{aagon.priorisierung}}
2 160
3 {{/aagon.priorisierung}}
4
5
6 {{aagon.floatingbox/}}
7
8 = Initial situation =
9
10 This Use Case shows you step by step how to send the [[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]] to a Client via the AESB Interface using a Client Command. The available Clients are loaded from the database and displayed in a list. A search field allows the user to filter for specific Client Commands. The hits are retrieved from the database and also displayed in a list. To prevent the Client Commands from being sent inadvertently, the user must tick a checkbox. This is to confirm that the selected Client and Client Command are correct.
11
12 For ease of understanding, much of the content of the //Form Editor //is explained in the Code View.
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 view for the following Client Command Use Case
20 {{/figureCaption}}
21 {{/figure}}
22
23 {{aagon.infobox}}
24 Read here how to [[install AESB>>doc:AESB.19.AESB installieren, konfigurieren und aktualisieren.AESB Core-Komponenten installieren.WebHome]] and how the [[ACMP and AESB components are connected>>doc:AESB.19.AESB installieren, konfigurieren und aktualisieren.SICS-Verbindung konfigurieren.WebHome]].
25 {{/aagon.infobox}}
26
27 == Select Script ==
28
29 1. Navigate to the //Client Commands// > //Create// module.
30 1. Click //Add// on the ribbon bar. The Client Command Editor will open and you will need to decide whether it is a Console or Client Script. In this case select the Console Script.
31
32 == To select and edit the //Set project variable //Command ==
33
34 1. Select the //Variables// > //Set project variable// command from the Command list..
35 1. Double click the Command and select the //General// tab.
36 1. Enter a name under //Description of actions//. In this example, "Set the AESB user name here" is inserted. All other configuration options in this tab do not need to be customised.
37 1. Switch to the //Details// tab.
38 1. Under Variable Settings, click on the icon next to the variable name.
39 1. Optional: Create a new variable under //Actions//. Name it "USERNAME" and click on the plus sign. Then click on the //OK// button to complete the step and have the entry listed as the variable name.
40
41 {{aagon.infobox}}
42 This step is optional if this variable has not yet been created in your system.
43 {{/aagon.infobox}}
44
45 7. In the //Single line// text box, enter „Operator“. This is required here as an identifier for the user name.
46 8. Click //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 Making variable settings
54 {{/figureCaption}}
55 {{/figure}}
56
57 == To select and edit a Command //Set project variable// ==
58
59 1. Select the Command //Set project variable// again.
60 1. Double click on the Command and open the //General// tab.
61 1. Under Description, enter the name of the action, e.g. //Set the AESB user password// here. Do not make any further changes to the other settings, they are not necessary.
62 1. Switch to the //Details// tab.
63 1. Optional: Create a new variable in the //variable settings//. To do this, click on the icon next to the list entries and a new window will open. Name the new variable "PASSWORD" and click on the plus sign. Click //OK// to complete this step.
64
65 {{aagon.infobox}}
66 This step is optional if you have not already created this variable.
67 {{/aagon.infobox}}
68
69 6. Select the //Plain text// option if you have not already done so. The clear text password will be added to this line later.
70 7. Finish your work on this Command and click //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 Defining variable settings
78 {{/figureCaption}}
79 {{/figure}}
80
81
82 == Opening and editing the Command //Form Editor// ==
83
84 {{aagon.warnungsbox}}
85 The Client Command Form Editor is extremely complex and should only be used if you have sufficient knowledge of programming under Delphi scripts and also know how to use an [[IDE (Integrated Development Environment)>>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]].
86 {{/aagon.warnungsbox}}
87
88 You can edit the elements of the [[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]] using either the code view or the design view. To make it easier to understand, the following section deals with the visual design view only in isolated cases, and more with the code. This means that the explanations of the properties and events of the Object Inspector, which you can read [[here>>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"]], are no longer necessary.
89
90 Use this Client Command to create an interactive form where you can assign a selected Client Command to a Client. To do this, proceed as follows:
91
92 1. Select the Client Command Form Editor (//Dialogs// > //Form Editor//).
93 1. Double click on the Command, open the //General// tab and optionally customise the //description of the actions//. In this example the title remains //Form Editor//.
94 1. Switch to the //Edit Form// tab.
95 1. Click on the //Edit Form// button below the preview form. A new window opens for working with the Form Editor in the standard view, with some custom fields.
96
97 {{aagon.infobox}}
98 For more information on using the Form Editor or the IDE (Integrated Developer Environment) see [[here>>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"]].
99 {{/aagon.infobox}}
100
101 5. Switch from the design view to the code view by clicking on the tab at the bottom (see illustration). The view will change.
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 Form Editor view
109 {{/figureCaption}}
110 {{/figure}}
111
112 6. Switch to the //FormUnit// tab if you are not already there. Here you can see the code from the upper Custom Windows window from the design view. This code now needs to be customised for your purposes.
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 View of the code for the Custom Windows window
120 {{/figureCaption}}
121 {{/figure}}
122
123 == Customising the code ==
124
125 The code is divided into useful sections and explained below. Always insert the lines in the order shown here to ensure that the client commands work correctly. The form will be executed as it will be displayed later.
126
127 {{aagon.infobox}}
128 All information in the code that appears after a double slash is commented out and only serves to explain the following lines. They are not part of the execution.
129 {{/aagon.infobox}}
130
131
132 |(% style="width:859px" %)**Row section**|(% style="width:505px" %)**Description**
133 |(% style="width:859px" %)**Row 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 These rows define the display of the Form Editor for the user and describe what the display is filled with and what type of content is generated (data type: string, row 12).
148
149 In the rows, units are added (//uses//, rows 3 - 6) and variables (//var//, rows 7 - 12) are declared, which can be filled at a later time. The respective variable type (e.g. TStringlist, Integer or String) is shown after the variable names.
150
151
152 )))
153 |(% style="width:859px" %)**Row 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" %)This function is required to use certain special characters in strings. Some special characters in the string have a special meaning for the program: If you want to display these special characters, you must "escape" them. When escaping, the special character to be displayed is preceded by the same character or a specific other character, such as a "\".
162 |(% style="width:859px" %)**Row 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}}|(((
187 In this section, the variables for the AESB service function (//function// //SetAESBConfig//, row 22) are defined and filled with values. The function is required later (from row 142), but you must already configure it at this point.
188
189 Fill the rows of the function as follows:
190
191 Row 24: Enter the type of protocol here. The value 0 stands for an HTTP page, 1 for an HTTPS page. Insert a 1 here, as this is an encrypted request.
192
193 Row 25: Specify a number of seconds when the request to the AESB runs into a timeout. The default value "30 seconds" was specified here.
194
195 Row 26: The ExchangeType can either be filled with the type "Direct (0)" or "Routing (1)". The latter option is selected here.
196
197 Row 27: ResultMessages.Clear() deletes the string list.
198
199 Rows 28 - 29: The two variables //AAckMessages// and //AResult// can be left clear. To do this, enter '' after the equals sign.
200
201 Rows 30 - 31: The //AErrorCode// and //IResult// are each filled with the value 0.
202
203 Row 32: Enter the name or IP of the AESB Server you want to connect to. In this example it is '127.0.0.1'.
204
205 Row 33: Enter the port number you need for the connection (here: '3900').
206
207 Row 34: The //GetVarContent// function is used here, which refers to the project variable ('USERNAME'). The project variable must be created and filled outside the Form Editor in the Client Commands themselves.
208
209 Row 35: The //GetVarContent// function is used here, which refers to the project variable ('PASSWORD'). This project variable must also be created and filled outside the Form Editor in the Client Command itself.
210
211 Row 36: The variable TargetConnectionVariable must be filled with the value 'CONNECTION'. The protocol requires this type for this type of connection (type: Connection).
212
213 Row 37: The value of the ConnectionString remains clear (' ') and will be filled with values later on.
214
215 Row 38: The MessageID is a GUID that can be exchanged and used as desired. When entering it, however, it is important that it follows the same input scheme: The number of digits must remain the same (8-4-4-4-8 digits each).
216
217 Row 39: The value 'VCMN' must be entered for the VirtualRouter. This is a virtual section within the AESB in which the ACMP Server is located. As this example communicates with the ACMP, this router must be specified.
218
219 Row 40: The RoutingKey specifies where the entered values are to be sent. Accordingly, the ACMP Server that is to receive the entries must be entered here. In this example it is called '?.Aagon.Components.ACMPServer.*'. The question mark and the asterisk both represent a wildcard. The asterisk represents the ACMP Server ID. If you have several ACMP Servers connected to the AESB, you can also enter the ID of one Server to route the data only to it.
220
221 Row 41: The input row //Tag// describes the type of message. As the ICQL protocol is used here, the value to be entered must be 'ICQL'.
222
223 Lines 42 - 43: The virtual router (CallbackVirtualRouter, row 42) and routing key (CallbackRoutingKey, row 43) are displayed here. No response is required, so a '' is sufficient as a clear value after the equals sign in both rows.
224 )))
225 |(% style="width:859px" %)**Row 46 - 55**|(% style="width:505px" %)
226 |(% style="width:859px" %){{code language="none"}}function GetClientID : String;
227 var
228 Ltemp : TStringList;
229 begin
230 LTemp := TStringList.Create();
231 LTemp.CommaText := LClients.Strings[LBClients.ItemIndex];
232 Result := LTemp.Values['CLIENTID'];
233 LTemp.Free();
234 end
235 {{/code}}|(% style="width:505px" %)(((
236 The //GetClientID// function, with a return value of the String type, is described in rows 46 - 50. The function determines the Client ID of the Client selected in the interface from the //LBClients// list.
237
238 Row 46: Start of the //GetClientID// function with a string as the return value.
239
240 Rows 47 - 54: The value //LClients.Strings// contains the index of the Client you have selected. With this index, the corresponding Client is selected from the //LClients.Strings// list and temporarily stored in a temporary variable. The return value of the function (row 52) is set to the value "Client ID" from the temporary variable and thus corresponds to the Client ID that you have chosen as the selected agent from the list. The working memory is released again via row 53.
241 )))
242 |(% style="width:859px" %)**Row 56 - 65**|(% style="width:505px" %)
243 |(% style="width:859px" %){{code language="none"}}function GetClientCommandID : String;
244 var
245 Ltemp : TStringList;
246 begin
247 LTemp := TStringList.Create();
248 LTemp.CommaText := LClientCommands.Strings[LBClientCommands.ItemIndex];
249 Result := LTemp.Values['SCRIPTID'];
250 LTemp.Free();
251 end
252 {{/code}}|(% style="width:505px" %)(((
253 Rows 56 - 65 describe the //GetClientCommandID// function. The function determines the Client Command ID of the Client Commands selected in the interface from the //LBClientCommands// list.
254
255 Row 56: Start of the //GetClientCommandID// function with a string as the return value.
256
257 Rows 57 - 65: //LBClientCommands.ItemIndex// contains the index of the Client Command you have selected. This index is used to select the corresponding Client Command from the //LClientCommands.Strings// list and temporarily store it in a temporary variable. The return value of the function (row 52) is set to the value "Script ID" from the temporary variable and thus corresponds to the Client Command ID that you have chosen as the selected Client Command from the list.
258
259 The working memory is released via row 63 (//LTemp.Free()//).
260 )))
261 |(% style="width:859px" %)**Row 66 - 80**|(% style="width:505px" %)
262 |(% style="width:859px" %){{code language="none"}}function CreateMessageBody : String;
263 var
264 MessageBody : TStringList;
265 begin
266
267 MessageBody := TStringList.Create();
268 MessageBody.Add('<ICQL><ACMP><EnqueueClientCommand version="1">');
269 MessageBody.Add('<TEnqueueClientCommandRequest_V1 xmlns:xsi="http:~/~/www.w3.org/2001/XMLSchema-instance">');
270 MessageBody.Add('<ClientId>'+GetClientID+'</ClientId>');
271 MessageBody.Add('<ClientCommandId>'+GetClientCommandID+'</ClientCommandId>');
272 MessageBody.Add('</TEnqueueClientCommandRequest_V1></EnqueueClientCommand></ACMP></ICQL>');
273 Result := MessageBody.Text;
274 MessageBody.Free();
275 end {{/code}}|(% style="width:505px" %)(((
276 The rows 66 - 80 describe the functions for creating the message that is sent to the SICS / AESB. In the section where the MessageBody is defined and filled, the data type must first be defined. Row 72 contains various values that must be adhered to. ICQL stands for the format in which the SICS expects the request, as well as the value ACMP. //EnqueueClientCommand// specifies that a function is to be called to queue a Client Commands in version 1.
277
278 Rows 74 and 75 specify that the request must contain the Client ID and the //GetClientCommandID// as a day so that the recipients (in this case the ACMP Server) know which Client Command to send to which Client.
279
280 The return value (row 77) then contains the complete message. This is followed by a network share of the working memory via row 78.
281 )))
282 |(% style="width:859px" %)**Row 81 - 109**|(% style="width:505px" %)
283 |(% style="width:859px" %){{code language="none"}}procedure GetClients;
284 var
285 LSQL, LTemp : TStringList;
286 I : Integer;
287 begin
288 LSQL := TStringList.Create();
289 LTemp := TStringList.Create();
290
291 // SQLStatement zum Ermitteln der Clients
292 LSQL.Add('SELECT COMPUTERNAME, CLIENTID');
293 LSQL.Add('FROM CLT_CLIENTS');
294 LSQL.Add('WHERE ismanaged = 1');
295 LSQL.Add('ORDER BY COMPUTERNAME');
296
297 // Leeren der Listbox der Clients
298 LBClients.Clear();
299 LClients.Clear;
300 // Ausführen des Statements zum Beziehen der Clients aus der DB
301 SQLQuery(LSQL.Text,'','',LClients,true,30);
302
303 for i := 0 to (LClients.Count-1) do
304 begin
305 LTemp.Commatext := EscapeValues(LClients.Strings[i]);
306 LBClients.Items.Add(LTemp.Values['COMPUTERNAME']);
307 end
308 LSQL.Free();
309 LTemp.Free();
310 end;
311 {{/code}}|(% style="width:505px" %)(((
312 Rows 81 - 109 (//procedure GetClients//) retrieve the agents from the database and save them in the left box, which is filled with the entries directly when the window is started. To do this, two lists are first defined and then created (86 and 87). The SQL Query/SQL statement is then assembled and filled with values, which enables the Clients to be determined. Only the computer name and the Client ID are retrieved from the //CLT_Clients// table. The condition //ismanaged=1// ensures that only managed agents are involved. The list returned by the SQL server is sorted according to the computer name (89 - 94). The list box is emptied once before it is filled to prevent entries from still being present (96 and 97).
313
314 The //SQL Query// function applies the SQL statement and writes all clients to the global string list (//LClients//) (line 99). Lines 101 - 107 fill the interface of the list box that is displayed to you as a user. The list box is filled with the computer names that were previously retrieved from the SQL query. The last two rows (106 and 107) release the previously created lists.
315 )))
316 |(% style="width:859px" %)**Row 110 - 141**|(% style="width:505px" %)
317 |(% style="width:859px" %){{code language="none"}}procedure GetClientCommands;
318 var
319 LSQL, LTemp : TStringList;
320 I : Integer;
321 begin
322
323 LSQL := TStringList.Create();
324 LTemp := TStringList.Create();
325 LSQL.Add('DECLARE @Search nvarchar(200) = ' + QuotedStr(EDCCSearch.Text) + ';')
326 LSQL.Add('SELECT DESCRIPTION, SCRIPTID');
327 LSQL.Add('FROM SYS_SCRIPTS');
328 LSQL.Add('WHERE HASCLIENTSCRIPT = 1');
329 LSQL.Add('AND State = 7');
330 LSQL.Add('AND DESCRIPTION LIKE @Search');
331 LSQL.Add('ORDER BY DESCRIPTION');
332
333 // Leeren der Listbox der ClientCommands
334 LBClientCommands.Clear();
335 LClientCommands.Clear();
336 // Ausführen des Statements zum Beziehen der ClientCommands aus der DB
337 SQLQueryEx(LSQL.Text,'','',LClientCommands,true,emOpen,30);
338
339 for I := 0 to (LClientCommands.Count-1) do
340 begin
341 LTemp.Commatext := EscapeValues(LClientCommands.Strings[i]);
342 LBClientCommands.Items.Add(LTemp.Values['DESCRIPTION']);
343 end
344
345 LSQL.Free();
346 LTemp.Free();
347 end;
348 {{/code}}|(% style="width:505px" %)(((
349 These rows (110 - 141) are used to fill the right box with the Client Commands entries by loading them from the SQL database and inserting them there. First, two lists are defined (116 and 117). To determine the Client Commands, an SQL Query is created in rows 119 - 124. Row 118 uses the search field of the interface to retrieve only Client Commands with this name from the database. Entering the wildcard "%" retrieves all Client Commands from the database, entering "Test_%" only retrieves all Client Commands that begin with "Test_" in their name. (//LSQL.Add('DECLARE @Search nvarchar(200) = ' + QuotedStr(EDCCSearch.Text) + ';')).//
350
351 The list box and the global list of client commands are emptied via lines 127 and 128. The statement is then executed via the SQL query, whereby the retrieved client commands are written to the global string list (//LClientCommands//). Lines 132 - 136 fill the surface of the list box with the description (name) of the client command that was previously retrieved from the SQL query. The rows 138 and 139 release the functions again.
352 )))
353 |(% style="width:859px" %)**Row 142 - 151**|(% style="width:505px" %)
354 |(% style="width:859px" %){{code language="none"}}procedure FormActivate;
355 begin
356 LClients := TStringList.Create();
357 LClientCommands := TStringList.Create();
358
359 ResultMessages := TStringList.Create();
360 GetClients;
361 SetAESBConfig;
362 end;
363 {{/code}}|(% style="width:505px" %)//Procdure FormActivate// (rows 142 - 151) is called when the window is created. The global lists //LClients// and //LClientCommands// are created first (144 and 145). The //GetClients// method retrieves all Clients from the database and displays them in the interface (see upper function) (148). The //SetAESBConfig// function is called in row 149 and sets all variables that were previously set by you and that are necessary to communicate with the AESB (see function above).
364 |(% style="width:859px" %)**Row 152 - 160**|(% style="width:505px" %)
365 |(% style="width:859px" %){{code language="none"}}procedure OkButtonClick(Sender: TObject);
366 begin
367 LClients.Free();
368 LClientCommands.Free();
369
370 ResultMessages.Free();
371 CloseForm(0);
372 end;
373 {{/code}}|(% style="width:505px" %)(((
374 The function in rows 152 - 160 is called when the OK button is pressed. All lists are cleared so that there are no more entries in //LClients// or //LClientCommands//. Row 158 //CloseForm(0) //closes the form with the parameter 0.
375
376 {{aagon.infobox}}
377 You can enter any integer as a parameter in the brackets. By default, a -1 means that this block has failed. This number (-1) can be set when starting the Form Editor. If the CloseForm(-1) function is then called, this block will cause the Client Command to fail and no continuing Commands will be executed after this block.
378 {{/aagon.infobox}}
379 )))
380 |(% style="width:859px" %)**Row 161 - 169**|(% style="width:505px" %)
381 |(% style="width:859px" %){{code language="none"}}procedure CancelButtonClick(Sender: TObject);
382 begin
383 LClients.Free();
384 LClientCommands.Free();
385
386 ResultMessages.Free();
387 CloseForm(1);
388 end;
389 {{/code}}|(% style="width:505px" %)Rows 161 - 169 are called when the cancel button is pressed. As in the previous section, all lists are cleared and the //Closeform// (row 167) is filled with the parameter 1 in order to show a better distinction between the OK and Cancel button, whereby this value does not represent an error. This parameter can be used in the Client Command as the return value of the form to distinguish whether the OK or cancel button was pressed.
390 |(% style="width:859px" %)**Row 170 - 176**|(% style="width:505px" %)
391 |(% style="width:859px" %){{code language="none"}}procedure CBSureClick(Sender: TObject);
392 begin
393 if ((CBSure.Checked) AND (LBClients.ItemIndex > -1 ) AND (LBClientCommands.ItemIndex > -1 ))
394 then BtnSend.Enabled := True;
395 Else BtnSend.Enabled := False;
396 end;
397 {{/code}}|(% style="width:505px" %)(((
398 This line section is called when the //CBSure// checkbox is clicked ("I am sure"), which the user must enable before sending a Command. The process //procedure CBSureClick(Sender:TOBject//) (from row 170) ensures that the following conditions are met (171 - 175) and that the //Send Command// button is enabled as a result. The condition is:
399
400 If //CBSure (true)// (checkbox checked), a Client from the left box and a Client Command from the right box have been selected (ItemIndex must be larger than -1; so a selected item must be selected), then the Send Command button is enabled (//BtnSend.Enabled// :=True). Otherwise, the button is disabled on Else.
401 )))
402 |(% style="width:859px" %)**Row 177 - 194**|(% style="width:505px" %)
403 |(% style="width:859px" %){{code language="none"}}procedure BtnSendClick(Sender: TObject);
404 var
405 AESBMessage : String;
406 begin
407 AESBMessage := CreateMessageBody;
408 AddSICSConnectionV1(Protocol,Server,Port,Username,
409 Passwort,ConnectionTimeout,TargetConnectionVariable,false);
410 ConnectionString := GetVarContent('CONNECTION');
411 IResult := SICSPublishV1(ConnectionString, MessageID, VirtualRouter, RoutingKey, ExchangeType, Tag,
412 AESBMessage, CallbackVirtualRouter, CallbackRoutingKey, ResultMessages, AAckMessages, AResult, AErrorCode);
413 if (IResult = 0) then
414 begin
415 ShowMessage('Command has been send');
416 CBSure.Checked := false;
417 BtnSend.Enabled := false;
418 end;
419 Else Showmessage('An Error has occured: '+InttoStr(IResult));
420 end;
421 {{/code}}|(% style="width:505px" %)(((
422 The function procedure //BtnSendClick(Sender: TObject)// is defined in the following rows and then executed as soon as the user clicks on the button. The variable (AESBMessage), whose data type is a string, is declared (row 179).
423
424 The function //CreateMessageBody //is then called. In this function, the MessageBody is completely assembled once and returned as a return value. This return value is in turn inserted into the //AESBMessage// variable (row 181). The SICS connection is then created, which consists of the various parameters and the AddSICSConnectionV1 function. In line 183, the //ConnectionString// variable is filled with the //GetVarContent// function. The function retrieves the value from the client command variable with the name (parameter of the function) "Connection". Line 184 continues with the //IResult// variable, where the result of the function is saved as SICSPublishV1. The various parameters are sent to the AESB. This is followed by an if. then clause follows: The result (IResult) of the function is checked to see if the result is 0 and therefore there were no errors. The //ShowMessage// function is called, which opens a dialog box with the text "Command has been send" (line 188). In the next two lines, the properties "Checked" for the checkbox and "Enabled" for the button are set to //False//. This restores the objects to their original state. If an error has occurred, the Else part is executed (line 192) and a dialog "An Error has occured" is displayed, as well as the result of IResult (the error code).
425 )))
426
427 7. Once you have inserted or customised all the relevant information in the code, you can run the form from the quick selection bar using the //Start //button [[image:https://doc.aagon.com/bin/download/ACMP/65/ACMP-Solutions/Client%20Commands/Use%20Cases%20f%C3%BCr%20Client%20Commands/Client%20Command%20per%20Form%20Editor%20via%20AESB%20statisch%20an%20einen%20Client%20senden/WebHome/image-20240205143129-1.png?rev=1.1||alt="image-20240205143129-1.png"]] (F9). Note that this is not only a test to check for any syntax, spelling or logic errors, but also to send client commands to an agent. The following image shows the finished form as it may appear in your system.
428
429 {{figure}}
430 (% style="text-align:center" %)
431 [[image:66_Client Command_Use Case Form Editor Design Ansicht_832.png]]
432
433 {{figureCaption}}
434 Completed Client Commands in the Custom Window
435 {{/figureCaption}}
436 {{/figure}}
437
438 8. Close the open windows (Custom Window and Form Editor). You will be returned to the Form Editor interface and its preview.
439
440 9. Check the value entered under //Script Return Value//. It should be the integer '-1'.
441
442 {{figure}}
443 (% style="text-align:center" %)
444 [[image:66_Use Case Client Commands_AESB Form Editor fertig_510.png]]
445
446 {{figureCaption}}
447 Form Editor preview
448 {{/figureCaption}}
449 {{/figure}}
450
451 10. Click //OK//.
452
453 ~11. Save the finished Client Command and close the editor.
454
455 {{figure}}
456 (% style="text-align:center" %)
457 [[image:66_Use Case Client Commands_AESB fertiges Script_1487.png]]
458
459 {{figureCaption}}
460 Client Command Editor: Sending a Client Command statically to a Client using the Form Editor via AESB
461 {{/figureCaption}}
462 {{/figure}}
463
464 == Running through the Client Command phases ==
465
466 Before the Client Command can be used, it must go through the [[Test>>doc:ACMP.66.ACMP-Solutions.Client Commands.Client Command testen.WebHome]], [[Synchronise>>doc:ACMP.66.ACMP-Solutions.Client Commands.Client Command synchronisieren.WebHome]], [[Release>>doc:ACMP.66.ACMP-Solutions.Client Commands.Client Command freigeben.WebHome]] und [[Execute>>doc:ACMP.66.ACMP-Solutions.Client Commands.Client Command ausführen.WebHome]] phases. It is then possible to send the Client Commands statically to a Client via the AESB using the Form Editor.
467
468
© Aagon GmbH 2025
Besuchen Sie unsere neue Aagon-Community