Пишу плагин под Лоцман 8.5, использую асконовский шаблон плагина на delphi. Не могу найти способа определить имя сервера, к которому подключен клиент Лоцмана, на котором запускается плагин. Имя базы в переменной stDataBaseName, передаваемой в плагин клиентом, а где имя сервера? Так же вызывает затруднение поиск имени подключившегося пользователя. Методы СП не подходят, потому что имя сервера и имя пользователя нужно туда передавать при создании COM-объекта.
Я тоже не нашел, как получить имя сервера, к которому в данный момент подключен клиент Лоцмана. Поэтому поступил так, как делает сам Лоцман: имена серверов приложений читаются из реестра, после чего по-очереди пытаюсь подключиться к одному из серверов приложений.
Чтение списка серверов приложений:
procedure GetAppServerList(AList: TStrings);
var
LRegistry: TRegistry;
begin
AList.Clear();
AList.LineBreak := ';';
LRegistry := TRegistry.Create();
try
if LRegistry.OpenKeyReadOnly('Software\ASCON\Loodsman') then
begin
if LRegistry.ValueExists('ClientSP') then
AList.Text := LRegistry.ReadString('ClientSP')
else
AList.Text := LRegistry.ReadString('SP');
end;
finally
LRegistry.Free();
end;
end;
В получившемся списке будут имена серверов приложений только при DCOM-соединении. В случает подключения к сокет-серверу там будут пары ключ=значение, разделенный символом '|'. Например
Host=127.0.0.1|Port=4804|User=Test|Password=base64
Цитата: danver от 25.04.12, 06:29:55
Методы СП не подходят, потому что имя сервера и имя пользователя нужно туда передавать при создании COM-объекта.
Не понятно, что вы имеете ввиду.
С поиском в реестре хорошая идея, спасибо!
По поводу методов СП я вот о чём. Здесь же на форуме прочитал совет по подключению к СП через элемент delphi DCOMConnection, но ему нужно указывать имя сервера, которое я как раз и искал.
Имя сервера приложений нашлось в реестре. А как найти имя сервера баз данных Лоцмана? Если исключить, конечно, поиск в глобальном конфигурационном файле Лоцмана, как уж больно многоходовый.
После подключения к серверу приложений необходимо подключиться к базе данных с помощью вызова ConnectToDB. Параметры подключения к базам данных также хранятся в реестре, в виде пакета данных TClientDataSet.
Получение параметров подключения к базам:
function GetDBAuthListData: OleVariant;
var
LRegistry: TRegistry;
LSize: Integer;
P: Pointer;
begin
LRegistry := TRegistry.Create();
try
if LRegistry.OpenKeyReadOnly('Software\ASCON\Loodsman') then
begin
LSize := LRegistry.GetDataSize('DBList');
if LSize > 0 then
begin
Result := VarArrayCreate([0, LSize - 1], varByte);
P := VarArrayLock(Result);
LRegistry.ReadBinaryData('DBList', P^, LSize);
VarArrayUnLock(Result);
end;
end;
finally
LRegistry.Free();
end;
end;
Вызов ConnectToDB:
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;
Код примерный, показывает, как это можно сделать.
Спасибо за подробный ответ!
Только сейчас дошли руки попробовать предложенный вариант. В этом способе присутствует допущение, что пользователь будет иметь доступ только к одной базе, которая его и пустит, и имеется только один сервер приложений, к которому пользователь сможет подключиться. Если таких серверов и баз обнаружится несколько, с какой именно парой сервер-база работает плагин в данном случае, таким способом узнать не удастся.
А может быть всё-таки есть способ узнать имя сервера баз данных, к которому подключены базы? Его можно прочитать в глобальном конфигурационном файле, но что-то как найти этот файл, я тоже сообразить не могу.
.
Цитата: danver от 27.06.12, 05:01:58
В этом способе присутствует допущение, что пользователь будет иметь доступ только к одной базе, которая его и пустит, и имеется только один сервер приложений, к которому пользователь сможет подключиться.
Имя базы данных передается в плагин, поэтому оно известно точно. Неизвестно только имя сервера приложений, оно и ищется в реестре.
.
Цитата: danver от 27.06.12, 05:01:58
А может быть всё-таки есть способ узнать имя сервера баз данных, к которому подключены базы? Его можно прочитать в глобальном конфигурационном файле, но что-то как найти этот файл, я тоже сообразить не могу.
Посмотрите, что возвращает GetDBProperties, может значение DefaultDir поможет.
Помогло. Спасибо за подсказку!