Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.02.28;
Скачать: CL | DM;

Вниз

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

 
EgorovAlex ©   (2009-04-01 09:34) [0]

Делаю так:

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 то всё работает, а если не задан - получаю исключение, что значение не найдено в кэше актив директори. Как избежать исключения? Как проверить, что это значение задано, перед его запросом?


 
clickmaker ©   (2009-04-01 10:37) [1]

Usr.Get("EmailAddress" ?


 
EgorovAlex ©   (2009-04-01 10:40) [2]

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


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

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


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

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


 
EgorovAlex ©   (2009-04-01 12:38) [5]

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


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

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 18:38) [7]

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


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

Кстати, вот как описывается в 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, ибо там всё корректно.


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

EgorovAlex

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


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

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

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


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


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

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


 
EgorovAlex ©   (2009-04-01 20:10) [11]

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

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


 
Jungle ©   (2009-04-02 09:48) [12]

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

...
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-02 13:47) [13]

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



Страницы: 1 вся ветка

Текущий архив: 2010.02.28;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.009 c
1-1238486793
Jungle
2009-03-31 12:06
2010.02.28
TClientDataSet и освобождение памяти


1-1238665266
salexn
2009-04-02 13:41
2010.02.28
Проблема с динамической загрузкой пакета


13-1124615958
Darklight
2005-08-21 13:19
2010.02.28
Экземпляр класса ещё не создан как проверить его на null referenc


15-1260896939
Nic
2009-12-15 20:08
2010.02.28
Что думаете об ЭТОМ?! )


2-1261641926
Андрей_11
2009-12-24 11:05
2010.02.28
запрос БД с другого компьютера