Во-первых, если вы пишете свое приложение для работы с Лоцман.
Во-вторых, если вы пишете плагин и необходимо работать с WorkFlow из клиентов версии меньше 11, или когда необходимо выполнить какие-либо действия от имени пользователя, отличного от того, который запустил клиент.
Для подключения к серверу приложений необходимы следующие данные:
- Тип соединения: DCOM, сокет-соединение или веб-соединение. Работа с сервером приложений будет осуществляться с помощью классов TDCOMConnection, TSocketConnetion или TWebConnection соответственно.
- Имя сервера, порт для сокет-соединения, имя, пароль пользователя и имя прокси-сервера для веб-соединения.
- Имя базы данных.
- Способ аутентификации в базе данных: аутентификация средствами Windows или аутентификация средствами SQL-сервера.
- Имя и пароль пользователя для аутентификации средствами SQL-сервера.
Параметры подключения к серверу приложений хранятся в реестре, ими можно достаточно просто управлять администраторам предприятия, например, с помощью групповых политик.
Сервер приложений
Список серверов приложений хранится в реестре, в ветке
HKCU\Software\ASCON\Loodsman
, в одном из значений: SP
, ClientSP
или WorkFlowSP
. Если установлена галочке «Использовать общий список серверов», то в значении с именем SP
. Если галочка не установлена, то в значении ClientSP
для выбранного «Клиент» в списке «Приложение», или в значении WorkFlowSP
для выбранного «WorkFlow».
Параметры подключения к разным серверам хранятся в виде строки с разделителем
;
(точка с запятой).В строке подключения к серверу может находиться либо просто имя сервера (при этом тип соединения будет DCOM), либо набор
имя=значение
, разделенный символом |
. Имена значений следующие:Имя параметра | Описание |
---|---|
DisplayName | Название подключения |
ConnectionType | Тип соединения: 0 — DCOM 1 — сокет-соединения 2 — веб-соединение |
Host | IP-адрес для сокет-соединения, URL для веб-соединения |
Port | Порт сокет-сервера, по умолчанию 4804 |
Proxy | Прокси-сервер для веб-соединения |
User | Имя пользователя для веб-соединения |
Password | Пароль для веб-соединения |
Например, строка подключения к сокет-серверу выглядит примерно так:
DisplayName=192.168.0.1:4801|ConnectionType=1|Host=192.168.0.1|Port=4801
При установке соединения необходимо подключаться к серверам из списка по-порядку до тех пор, пока не удастся установить соединение.
Чтение списка серверов приложений в виде кода:
procedure GetAppServerList(const AWorkflow: Boolean; const AList: TStrings); var R: TRegistry; begin AList.Clear(); AList.LineBreak := ';'; R := TRegistry.Create(); try if R.OpenKeyReadOnly('Software\ASCON\Loodsman') then begin if AWorkflow and R.ValueExists('WorkFlowSP') then AList.Text := R.ReadString('WorkFlowSP') else if (not AWorkflow) and R.ValueExists('ClientSP') then AList.Text := R.ReadString('ClientSP') else AList.Text := R.ReadString('SP'); end; finally R.Free(); end; end;
Разбор строки с параметрами подключения:
procedure GetAppServerParams(const AConnectionString: String; var AConnection: TAppServerConnection; var AHost: String; var APort: Integer; var AProxy, AUserName, APassword: String); var LParams: TStringList; i: Integer; LName: String; LValue: String; begin AConnection := TAppServerConnection.DCOM; AHost := AConnectionString; APort := 4804; if Pos('|', AConnectionString) > 0 then begin LParams := TStringList.Create(); try LParams.LineBreak := '|'; LParams.NameValueSeparator := '='; LParams.Text := AConnectionString; for i := 0 to LParams.Count - 1 do begin LName := LParams.Names[i]; LValue := LParams.ValueFromIndex[i]; if LName = 'ConnectionType' then AConnection := TAppServerConnection( StrToIntDef(LValue, 0)) else if LName = 'Host' then AHost := LValue else if LName = 'Port' then APort := StrToIntDef(LValue, 4804) else if LName = 'Proxy' then AProxy := LValue else if LName = 'User' then AUserName := LValue else if LName = 'Password' then APassword := DeCrypt(LValue); end; finally LParams.Free(); end; end; end;
База данных
Информация о параметрах подключения к базам данных хранится в реестре в ветке
HKCU\Software\ASCON\Loodsman
в значении DBList
. Значение имеет тип REG_BINARY
и в нем хранится набор данных TClientDataSet.Набор данных содержит следующие поля:
Имя поля | Тип | Описание |
---|---|---|
_DataBase | VARCHAR(255) | Имя базы данных |
_UserName | VARCHAR(255) | Имя пользователя (только для аутентификации средствами SQL-сервера) |
_AccessMethod | INTEGER | Способ аутентификации: 0 — средствами Windows 1 — средствами SQL-сервера 2 — средствами SQL-сервера, пароль сохранен 3 — недоступная база данных |
_Password | VARCHAR(255) | Пароль пользователя (только для аутентификации средствами SQL-сервера) |
_Connected | INTEGER | Назначение поля точно не известно и в представленном коде не используется |
Для подключения к базе данных необходимо найти в наборе данных параметры подключения, если необходим пароль и он не сохранен, то спросить пароль у пользователя. Затем вызвать метод сервера приложений ConnectToDBEx и передать ему полученные параметры.
Код получения набора данных с параметрами подключения:
function GetDBAuthListData: OleVariant; var R: TRegistry; LSize: Integer; P: Pointer; begin R := TRegistry.Create(); try if R.OpenKeyReadOnly('Software\ASCON\Loodsman') then begin LSize := R.GetDataSize('DBList'); if LSize > 0 then begin Result := VarArrayCreate([0, LSize - 1], varByte); P := VarArrayLock(Result); R.ReadBinaryData('DBList', P^, LSize); VarArrayUnLock(Result); end; end; finally R.Free(); end; end;
procedure ConnectTo(const ABase: String); var LDatabaseAuth: Integer; LDBListData: OleVariant; LDataSet: TClientDataSet; LUserName: String; LPassword: String; begin LDatabaseAuth := 0; LDBListData := GetDBAuthListData(); if not VarIsEmpty(LDBListData) then begin LDataSet := TClientDataSet.Create(nil); try LDataSet.Data := LDBListData; if LDataSet.Locate('_DataBase', ABase, []) then begin LDatabaseAuth := LDataSet.FieldValue['_AccessMethod']; LUserName := LDataSet.FieldValue['_UserName']; LPassword := LDataSet.FieldValue['_Password']; if LPassword <> '' then LPassword := DeCrypt(LPassword); if (LDatabaseAuth in [1, 2]) and (LPassword = '') then begin // Запрос имени пользователя и пароли, // если они не сохранены ShowLoodsmanLoginDialog(ABase, LUserName, LPassword); end; end; finally LDataSet.Free(); end; end; if LDatabaseAuth in [1, 2] then DCOMConnection.ConnectToDBEx(ABase, LUserName, LPassword) else DCOMConnection.ConnectToDB(ABase); end;
Краткий пересказ статьи я писал на форуме Аскона, в теме Как в плагине Лоцмана определить имя сервера, к которому подключен клиент?
В следующей статье мы рассмотрим подключение к серверу и вызов методов сервера приложений.
Комментариев нет:
Отправить комментарий