Как в плагине Лоцмана определить имя сервера, к которому подключен клиент?

Автор danver, 25.04.12, 06:29:55

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

danver

Пишу плагин под Лоцман 8.5, использую асконовский шаблон плагина на delphi. Не могу найти способа определить имя сервера, к которому подключен клиент Лоцмана, на котором запускается плагин. Имя базы в переменной stDataBaseName, передаваемой в плагин клиентом, а где имя сервера? Так же вызывает затруднение поиск имени подключившегося пользователя. Методы СП не подходят, потому что имя сервера и имя пользователя нужно туда передавать при создании COM-объекта.

Chaa

Я тоже не нашел, как получить имя сервера, к которому в данный момент подключен клиент Лоцмана. Поэтому поступил так, как делает сам Лоцман: имена серверов приложений читаются из реестра, после чего по-очереди пытаюсь подключиться к одному из серверов приложений.
Чтение списка серверов приложений:
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-объекта.
Не понятно, что вы имеете ввиду.

danver

С поиском в реестре хорошая идея, спасибо!

По поводу методов СП я вот о чём. Здесь же на форуме прочитал совет по подключению к СП через элемент delphi DCOMConnection, но ему нужно указывать имя сервера, которое я как раз и искал.

Имя сервера приложений нашлось в реестре. А как найти имя сервера баз данных Лоцмана? Если исключить, конечно, поиск в глобальном конфигурационном файле Лоцмана, как уж больно многоходовый.

Chaa

После подключения к серверу приложений необходимо подключиться к базе данных с помощью вызова 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

Спасибо за подробный ответ!
Только сейчас дошли руки попробовать предложенный вариант. В этом способе присутствует допущение, что пользователь будет иметь доступ только к одной базе, которая его и пустит, и имеется только один сервер приложений, к которому пользователь сможет подключиться. Если таких серверов и баз обнаружится несколько, с какой именно парой сервер-база работает плагин в данном случае, таким способом узнать не удастся.
А может быть всё-таки есть способ узнать имя сервера баз данных, к которому подключены базы? Его можно прочитать в глобальном конфигурационном файле, но что-то как найти этот файл, я тоже сообразить не могу.

Chaa

.
Цитата: danver от 27.06.12, 05:01:58
В этом способе присутствует допущение, что пользователь будет иметь доступ только к одной базе, которая его и пустит, и имеется только один сервер приложений, к которому пользователь сможет подключиться.
Имя базы данных передается в плагин, поэтому оно известно точно. Неизвестно только имя сервера приложений, оно и ищется в реестре.

.
Цитата: danver от 27.06.12, 05:01:58
А может быть всё-таки есть способ узнать имя сервера баз данных, к которому подключены базы? Его можно прочитать в глобальном конфигурационном файле, но что-то как найти этот файл, я тоже сообразить не могу.
Посмотрите, что возвращает GetDBProperties, может значение DefaultDir поможет.