Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правильно прочитать значение из IADsUser


EgorovAlex ©   (2009-04-01 09:34:00) 

Делаю так:

var
 Usr: OleVariant;
begin
 if (ADsGetObject(PWideChar('LDAP://' + ADPath), IID_IADsUser, Usr) = S_OK) then
 try
   Result := IADsUser(Usr).EmailAddress;
 finally
   Usr := Unassigned;
 end;
end;

Если для пользователя задан email то всё работает, а если не задан - получаю исключение, что значение не найдено в кэше актив директори. Как избежать исключения? Как проверить, что это значение задано, перед его запросом?


EgorovAlex   (2009-04-02 13:47:00) [1]

Спасибо, попробую


Jungle   (2009-04-02 09:48:00) [2]

Ну вот сварганил нечто на скорую руку :)

...
uses ADOInt;

{$R *.dfm}

var
 adoconn: _Connection;
 ConnStr: WideString;

...

procedure TForm1.FormCreate(Sender: TObject);
begin
 adoconn := CoConnection.Create;

 if ( not VarIsEmpty(adoconn) ) then
 begin
   ConnStr := 'Provider=ADsDSOObject;Encrypt Password=True;Mode=Read;Bind Flags=0;ADSI Flag=-2147483648';
   adoconn.Open(ConnStr, ' login', ' password', -1);

   if ( not adoconn.State = adStateOpen ) then
     MessageBox(0, PChar('Can''t establish connection!'), PChar('Error!'), MB_ICONERROR );
 end
 else
   MessageBox(0, PChar('Can''t create ADOConnection!'), PChar('Error!'), MB_ICONERROR );
end;

...

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 try
   adoconn.Close;
 finally
   adoconn := nil;
 end;
end;

...
procedure TForm1.Button1Click(Sender: TObject);
var
 ars:_Recordset;
 acm:_Command;
 S: string;
 v : Variant;

begin
 Memo1.Clear;

 if ( adoconn.State = adStateOpen ) then
 try
   ars := CoRecordset.Create;

   if ( not VarIsNull(ars) ) then
   try
     acm := CoCommand.Create;

     if ( not VarIsNull(acm) ) then
     begin
       acm.Set_ActiveConnection(adoconn);
       acm.CommandText := 'SELECT samAccountName, mail FROM ''LDAP:// yourdomain'' ' +
                          'WHERE objectClass=''user'' AND (sn = ''*'') ' +
                          'AND (givenName = ''*'') AND (samAccountName <> ''*$'') Order by samAccountName';
       ars.Open(acm, EmptyParam, adOpenDynamic, adLockReadOnly, adCmdText);

       if ( ars.State = adStateOpen ) then
       begin
         ars.MoveFirst;

         while ( not ars.EOF ) do
         begin
           s := EmptyStr;
           
           v := ars.Fields.Item['samAccountName'].Value;
           if ( not VarIsNull(v) ) then
             s := s + String(v);

           v := ars.Fields.Item['mail'].Value;
           if ( not VarIsNull(v) ) then
             s := s + '; ' + String(v);

           Memo1.Lines.Add(s);
           ars.MoveNext;
         end;

         ars.Close;
       end;
     end;
   finally
     acm := nil;
   end;
 finally
   ars := nil;
 end;
end;

...


У меня работает без ошибок - при условии, что запрос корректен.


EgorovAlex   (2009-04-01 20:10:00) [3]

Почти понятно :) ... так как это всё у меня должно быть из сервиса :), т.е. только чистый код, без компонент, ну или с ними, но там уже инициализация нужна...  

Спасибо заранее


Jungle   (2009-04-01 19:55:00) [4]


> В SQL.Text у ADOQuery пишешь тот запрос

Ну, только домен свой пропишешь естественно :)


Jungle   (2009-04-01 19:53:00) [5]

EgorovAlex

> А как это будет выглядеть на делфи?


Прям так и будет :)

Для иллюстрации.
Кидаешь на форму TADOConnection, формируешь строку подключения, в которой в качестве драйвера указываешь драйвер OLE DB для службы каталогов. Потом, соответственно, TDataSource и TADOQuery. В SQL.Text у ADOQuery пишешь тот запрос.

Пишу из дома, Delphi не установлен. Завтра могу более точно написать.


Jungle   (2009-04-01 19:46:00) [6]

Кстати, вот как описывается в MSDN'е функция Get: h__p://msdn.microsoft.com/en-us/library/aa746347(VS.85).aspx

Приведённый в вышеуказанной статье пример можно немного адаптировать:
...
 hr = pUsr->Get(L"Mail", &var);
 if ( SUCCEEDED(hr) )
 {
   printf("Mail: %S\n", V_BSTR(&var) );
   VariantClear(&var);
 }
...


Он отрабатывает без возникновения исключений - проверено.

Поэтому я в своё время для разработки приложения, работающего с ADSI, отказался от Delphi в пользу C++ Builder, ибо там всё корректно.


EgorovAlex   (2009-04-01 18:38:00) [7]

А как это будет выглядеть на делфи?


Jungle   (2009-04-01 14:16:00) [8]

EgorovAlex

Может, тогда проще использовать WQL?

Вот, например, запрос:
SELECT sn, Initials, givenName, department, samAccountName, mail
FROM 'LDAP://yourdomain'
WHERE objectClass='user' AND (sn = '*') AND (givenName = '*')
AND (samAccountName <> '*$')
Order by sn


EgorovAlex   (2009-04-01 12:38:00) [9]

Так это понятно, как избавиться от его показа, хочется его избежать, не люблю я заранее известные, но не отловленные исключения, как-то не правильно это


Jungle   (2009-04-01 12:34:00) [10]

Точнее, сообщение об ошибке выводиться не будет


Jungle   (2009-04-01 12:16:00) [11]

Если хочешь, чтобы не было исключения - замени finallyна except


EgorovAlex   (2009-04-01 10:40:00) [12]

Пробовал, та же реакция и Usr.GetEx то же


clickmaker   (2009-04-01 10:37:00) [13]

Usr.Get('EmailAddress' ?


Наверх

Титульная страница Поиск, карта сайта Написать письмо