Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Понимание правильного закрытия соединения в Delphi при использовании ADsOpenObject

Delphi , Файловая система , Активные директории

ADSI и Delphi: Правильное закрытие соединения при использовании ADsOpenObject

При работе с Active Directory Service Interfaces (ADSI) в Delphi одним из распространенных вопросов является правильное закрытие соединения после его использования. В этой статье мы рассмотрим, как решить проблему неправильного закрытия соединения, которая может возникнуть при использовании функции ADsOpenObject.

Описание проблемы

Рассмотрим следующий код, в котором демонстрируется попытка получить путь группы Windows по имени пользователя и паролю:

procedure ShowADSPath(UserName, Password: widestring);
var
  Group: IADs;
begin
  try
    OleCheck(ADsOpenObject('WinNT://Server/Group1',
      UserName,
      Password, ADS_SECURE_AUTHENTICATION, IADs, Group));
    if (Group <> nil) and (Group.Class_ = 'Group') then
      ShowMessage(Group.ADsPath);
    Group.release;
    Group := nil;
  except
    ShowMessage('NOT ACCESSDE');
  end;
end;

Проблема заключается в том, что после первого успешного или неудачного вызова этой функции, последующие вызовы могут возвращать неверные результаты, независимо от правильности введенных имени пользователя и пароля. Это происходит из-за неправильного закрытия соединения с сервером.

Подтвержденный ответ

После тщательного исследования был найден Decision 218497 в базе знаний Microsoft, который описывает подобную проблему с API функцией ADsOpenObject. Функция открывает соединение с сервером, используя переданные ей учетные данные, но не закрывает его после завершения работы. Попытки закрыть соединение не приводят к ожидаемым результатам, так как оно не закрывается в текущей сессии.

Чтобы решить проблему, можно использовать другой API для проверки существования объекта перед открытием соединения. Вот пример функции, которая решает проблему:

procedure ShowADSPath(UserName, Password: widestring);
function CheckObject(APath: String): IDispatch;
var
  Moniker: IMoniker;
  Eaten: Integer;
  BindContext: IBindCtx;
  Dispatch: IDispatch;
begin
  Result := nil;
  OleCheck(CreateBindCtx(0, BindContext));
  OleCheck(MkParseDisplayName(BindContext, PWideChar(WideString(APath)),
    Eaten, Moniker));
  OleCheck(Moniker.BindToObject(BindContext, nil, IDispatch, Dispatch));

  Result := Dispatch;
end;

var
  Group: IADs;
begin
  try
    if CheckObject('WinNT://Server/Group1,group') <> nil then
    begin
      OleCheck(ADsOpenObject('WinNT://Server/Group1,group',
        UserName,
        Password, ADS_SECURE_AUTHENTICATION, IADs, Group));
      if (Group <> nil) and (Group.Class_ = 'Group') then
      begin
        ShowMessage(Group.ADsPath);
        Group.release;
        Group := nil;
      end;
    end;
  except
    ShowMessage('NOT ACCESSDE');
  end;
end;

В этой функции CheckObject сначала проверяет existence объекта, а затем, если объект существует, открывает соединение с сервером и получает путь группы. Это гарантирует правильное закрытие соединения после его использования.

Альтернативный ответ

Хотя решение, описанное выше, является наиболее надежным способом решить проблему, существует альтернативный подход, заключающийся в использовании объекта IADsContainer для получения членов группы. Этот подход не требует закрытия соединения явно, так как объект IADsContainer автоматически закрывается после использования. Вот пример кода, демонстрирующего этот подход:

procedure ShowGroupMembers(UserName, Password: widestring; GroupName: string);
var
  Group: IADsContainer;
begin
  try
    OleCheck(ADsOpenObject('WinNT://Server/' + GroupName,
      UserName,
      Password, ADS_SECURE_AUTHENTICATION, IADsContainer, Group));
    if Group <> nil then
    begin
      var
        Member: IADs;
      for Member in Group do
      begin
        if Member.Class_ = 'user' then
          ShowMessage(Member.ADsPath);
        Member.release;
      end;
      Group.release;
    end;
  except
    ShowMessage('NOT ACCESSDE');
  end;
end;

В этом примере функция ShowGroupMembers открывает объект IADsContainer для указанной группы и перебирает всех членов группы, отображая путь каждого члена пользователя. После завершения работы с объектом IADsContainer он автоматически закрывается, что гарантирует правильное закрытие соединения.

Заключение

При работе с ADSI в Delphi важно правильно закрывать соединение после его использования. В противном случае могут возникнуть проблемы с получением неверных результатов при повторных вызовах функций, работающих с ADSI. Использование функции CheckObject для проверки existence объекта перед открытием соединения или использование объекта IADsContainer для получения членов группы являются надежными способами решить проблему неправильного закрытия соединения.

Создано по материалам из источника по ссылке.

В статье рассматривается проблема правильного закрытия соединения при использовании ADsOpenObject в Delphi для работы с Active Directory Service Interfaces (ADSI). При неправильном закрытии соединения могут возникать проблемы с получением неверных результ


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Активные директории ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-28 05:20:37/0.0035130977630615/0