Общий смысл работы кастомизации:
Во время инициализации
отображения элементов на UI сделать запрос в базу данных на предмет
наличия у текущего StoreApp(это может быть и приложение и десктоп)
активных сессий и показать это пользователю.
Использовал эти источники:
https://developer-docs.citrix.com/en-us/storefront/storefront-client-ui-customization-api/api-reference.html
https://www.simonscitrix.com/2018/01/customizing-storefront-with-awl-citrix.html?m=1
https://www.citrixguru.com/2016/03/08/lab-ultimate-storefront-customization-guide/
https://www.carlstalhood.com/storefront-cr-tweaks/#customize3
Как это работает:
В FtoreFront заложен механизм катомизации UI, позволяющий перехватывать некоторые события и производить изменения.
Для перехвата используется скрипт
«C:\inetpub\wwwroot\Citrix\StoreWeb\custom\script.js».
Он позволяет также отправить ajax запрос на сервер и изменить UI. В качестве сервера я использовал IIS+PHP.
Запрос: script.js
//Detail Info customization CTXS.Extensions.beforeShowAppInfo = function(app) { var ihElement = document.querySelector('section.appInfoView.scrollable div.appInfoHeader div.appInfoHeaderDetails'); if (ihElement) { var custP = ihElement.querySelectorAll('p'); if (custP) { for ( item of custP) { item.remove(); } } } CTXS.ExtensionAPI.proxyRequest({ type: "POST", url: "/PHP/get.php", timeout: 1000, data: { msg: app.desktophostname }, success: function(msg){ if (msg != '') { customize(0, msg, null); } } }); }; //App Tile customization CTXS.Extensions.getAppTileMarkup = function (app, appDisplayName, defaultMarkupFn) { //console.log(app); CTXS.ExtensionAPI.proxyRequest({ type: "POST", url: "/PHP/get.php", timeout: 1000, data: { msg: app.desktophostname }, success: function(msg){ if (msg != '') { customize(0, msg, app.shortid); } } }); return defaultMarkupFn(); } function customize(num, msg, appShortid) { var appElement, stl; if (appShortid != null) { stl = ' style="margin-top: -36px" '; var appElement = document.querySelector('[data-shortid="' + appShortid + '"]'); } else { stl = ' style="margin: 12px 0px" '; var appElement = document.querySelector('section.appInfoView.scrollable div.appInfoHeader div.appInfoHeaderDetails'); } if (appElement) { var AppStatus = msg.split(';'); var ins = ''; if (AppStatus[2] == 1) { //InMaintenanceMode ins = '<p class="storeapp-name" style="margin-top: -30px; color: red">Режим обслуживания</p>' } else { if (AppStatus[3] > 0) { //_SessionCount if (AppStatus[5] >= 2) { //SessionState var d1 = Date.parse(AppStatus[4]) //LogOnTime var now = new Date(); var diff = Math.round((Math.abs(now.getTime() - d1) / 3600000) - 4); ins = '<p class="storeapp-name" '+stl+'><span style="color: green">Сессия:</span> '+AppStatus[6]+' '+diff+' ч.<br>'+(AppStatus[5]==2 ? '<span style="color: green">Connected</span>' : '<span style="color: gray">Disconnected</span>')+'</p>' } else { ins = '<p class="storeapp-name" '+stl+'>Подключение...</p>' } } } //инъекция HTML кода appElement.insertAdjacentHTML('beforeend', ins); } else { if (num < 20) { setTimeout(function() { customize(num+1, appShortid, msg); }, 100); } } }
Сервер:
Настроил в IIS поддержку PHP пошаговый разбор есть здесь
https://www.dmosk.ru/instruktions.php?object=iis-php
Скачал драйвер MS SQL для PHP
https://learn.microsoft.com/en-us/sql/connect/php/download-drivers-php-sql-server?view=sql-server-ver16
Подключил его в php.ini
extension=C:\php-8.3.6-Win32-vs16-x64\ext\php_sqlsrv_83_ts_x64.dll
Установил ODBC драйвер (18 версии, более младшие выдавали ошибку)
https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server?view=sql-server-ver16
В базе данных создал учетку CTX_get для доступа к базе на чтение.
В UserMappings указал маппинг на БД сайта Citrix_site_database и указал роли db_datareader + chrBroker(потребовалось для выполнения процедуры запроса chb_State.PickMainVDISession)
За основу своего запроса взял запрос, который использует Citrix при выполнении powerShell команды Get-BrokerMachine. Там огромный тяжелый запрос, я оставил в нем только то что мне надо было.
get.php
<?php $conn = sqlsrv_connect('<SQL server name>\SQLEXPRESS,1433', array('Database'=>"Citrix_site_database", 'UID'=>'CTX_get', 'PWD'=>'PASSWORD', 'Encrypt'=>'False')); $req = "select CW.Uid as _Uid, WD.HostedMachineName, CW.InMaintenanceMode, ( W.CurrentSessions + W.PendingSessions ) as _SessionCount, S.LogOnTime, S.SessionState, TUN.SAMName as _SessionUserName from chb_Config.Workers CW inner join chb_State.Workers W on CW.Uid = W.Uid inner join chb_State.WorkerDiags WD on CW.Uid = WD.Uid left outer join chb_State.Sessions S on ( (W.SessionSupport = 0) and (S.WorkerUid = W.Uid) and ( S.Uid = case when (W.CurrentSessions <= 0) or (W.SessionSupport <> 0) then null when (W.CurrentSessions = 1) then S.Uid else chb_State.PickMainVDISession(W.Uid) end ) ) left outer join chb_State.AccountNames TUN on S.TrustedUserUid = TUN.Uid where WD.HostedMachineName = '".$_POST['msg']."';"; //условие по имени машины $res = sqlsrv_query($conn, $req); if ($res) { $rows = sqlsrv_has_rows( $res ); if ($rows === true) { $row = sqlsrv_fetch_array( $res, SQLSRV_FETCH_ASSOC); $ret = ''; foreach ($row as $item) { if (is_a($item, 'DateTime')) { $ret .= $item->format('Y-m-d H:i:s') . ';'; } else { $ret .= $item.';'; } } echo $ret; } } sqlsrv_free_stmt( $res); ?>
Комментариев нет:
Отправить комментарий