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

Вниз

Как преобразовать OleVariant в IAdsMembers? Пытаюсь так:   Найти похожие ветки 

 
EgorovAlex ©   (2005-11-06 12:00) [0]


var
 Group: IADsGroup;
 Members: IAdsMembers;
 varMembers: OleVariant;
...
ADsGetObject("LDAP://" + AdsPath, IADsGroup, Group);
varMembers := Group.GetEx("MemberOf");
Members := IDispatch(varMembers) as IAdsMembers;

так вот на последней строке ругается:
Could not convert variant of type(Array Variant) into type (Dispatch).

Как же мне его туда загнать?


 
Набережных С. ©   (2005-11-06 12:38) [1]

IDispatch(Members):=varMembers;
Members:=Members as IAdsMembers;

или

if TVarData(varMembers).VType = varDispatch then
 Members:= IDispatch(TVarData(varMembers).VDispatch) as IAdsMembers;

Или, более строго, объявить дополнительную переменную типа Idispatch и передать через нее.


 
EgorovAlex ©   (2005-11-06 14:57) [2]

К сожалению не работает :(

Вот оригинальный код на vbs, который работает:


Set objGroup = GetObject("LDAP://" & AdsPath)

arrMembersOf = objGroup.GetEx("MemberOf")

WScript.Echo "MembersOf:"
For Each strMemberOf in arrMembersOf
   WScript.Echo strMemberOf
Next


Т.е. это заведомо правильная конструкция, а у меня в отладчике для varMembers Delphi пишет, что это "Variant array of Variant" и тип TVarData(varMembers).VType = 8204


 
Набережных С. ©   (2005-11-06 15:32) [3]


> EgorovAlex ©   (06.11.05 14:57) [2]

Ну так и чего же тогда искать в нем интерфейс, если приходит массив?
8204 - array of Variant (см. Variant type codes в System.pas). Вот и смотри, что там в каждом из элементов этого массива, типа
for n:=VarArrayLowBound(varMembers, 1) to VarArrayHighBound(varMembers, 1) do
 ...varMembers[n]....

И DimCount тоже проверь.


 
EgorovAlex ©   (2005-11-06 15:41) [4]

Спасибо, помогло. В элементах этого массива OleStr находятся.


 
EgorovAlex ©   (2005-11-08 11:56) [5]

Написал такую процедуру получения всех глобальных вложенных групп для пользователя в домене, она работает правильно:

function GetAllGroupsForUser(DomainName, UserName: WideString; Groups: TStrings): Boolean;
var
 varGroups: TStringList;

 procedure GetGroupsForGroup(AdsPath, GroupName: WideString);
 var
   Connection, Command, Res: Variant;
   Group: IADsGroup;
   varMembers: OleVariant;
   varGroup, varType: WideString;
   I, N, L: Integer;
 begin
   if (AdsPath = "") then
   begin
     Connection := CreateOleObject("ADODB.Connection");
     Command := CreateOleObject("ADODB.Command");
     try
       Connection.Provider := "ADsDSOObject";
       Connection.Open("Active Directory Provider");

       Command.ActiveConnection := Connection;
       Command.Properties("Page Size") := 1000;
       Command.Properties("Searchscope") := ADS_SCOPE_SUBTREE;
       Command.CommandText := "SELECT distinguishedName FROM ""LDAP://" + DomainName +
                              """ WHERE objectCategory=""group"" AND sAMAccountName=""" + GroupName + """";
       try
         Res := Command.Execute;
         if not Res.EOF then
           AdsPath := Res.Fields[0].Value;
       except
       end;
       Res := NULL;
     finally
       Command := NULL;
       Connection.Close;
       Connection := NULL;
     end;
   end;
   if (AdsPath <> "") then
   begin
     ADsGetObject("LDAP://" + AdsPath, IADsGroup, Group);
     try
       varMembers := Group.GetEx("MemberOf");
       for I := 0 to VarArrayHighBound(varMembers, 1) do
       begin
         varGroup := varMembers[I];
         N := Pos("CN=", varGroup);
         Delete(varGroup, 1, N + 2);
         varType := varGroup;
         N := Pos(",", varGroup);
         L := Length(varGroup);
         Delete(varGroup, N, L);
         if (Groups.IndexOf(varGroup) = -1) then
         begin
           Groups.Add(varGroup);
           N := Pos("CN=", varType);
           if (N > 0) then
           begin
             Delete(varType, 1, N + 2);
             N := Pos(",", varType);
             Delete(varType, N, L);
             if not WideSameText(varType, "Builtin") then
               varGroups.Add(varMembers[I]);
           end;
         end;
       end;
     except
     end;
   end;
 end;

var
 Enum: IEnumVariant;
 User: IADsUser;
 Members: IAdsMembers;
 Group: IAdsGroup;
 varGroup: OleVariant;
 Temp: LongWord;
begin
 Result := False;
 varGroups := TStringList.Create;
 try
   if WideSameText(DomainName, LocalComputer) then
   begin
   end
   else
   try
     ADsGetObject("WinNT://" + DomainName + "/" + UserName, IADsUser, User);
     Members := User.Groups;
     Enum := Members._NewEnum as IEnumVariant;
     if Assigned(Enum) then
       while (Enum.Next(1, varGroup, Temp) = S_OK) do
       begin
         Group := IDispatch(varGroup) as IAdsGroup;
         Groups.Add(Group.Name);
         GetGroupsForGroup("", Group.Name);
         VariantClear(varGroup);
       end;
   except
   end;

   while (varGroups.Count > 0) do
   begin
     GetGroupsForGroup(varGroups[0], "");
     varGroups.Delete(0);
   end;
 finally
   varGroups.Free;
 end;
end;

procedure TForm1.btnUserAdsPathClick(Sender: TObject);
var
 C: Cardinal;
begin
 memGroups.Lines.Clear;
 C := GetTickCount;
 GetAllGroupsForUser(edtDomain.Text, edtUser.Text, memGroups.Lines);
 Form1.Caption := IntToStr(GetTickCount - C);
//  Caption := Form1.Caption;
end;


Так вот самое интересное и непонятное - после её вызова в btnUserAdsPathClick теряются значения переменной С и Self, т.е. если расскоментировать последнюю строчку, то вылетает исключение и в переменной C совсем не то значение, которое было перед вызовом.
Как такое может быть и где ковыряться для исправления? (Delphi 7)


 
Digitman ©   (2005-11-08 12:25) [6]

встроенный отладчик Борландом был писан не для Пушкина, а для тебя)


 
EgorovAlex ©   (2005-11-08 12:39) [7]

Я понимаю, но во время трассировки моей функции всё нормально работает и показывает, а вот после выхода из неё переменные C и Self уже испорчены.


 
Набережных С. ©   (2005-11-08 12:51) [8]

Откуда берешь декларации? В общем, покажи декларации всех использованных импортных функций и интерфейсов.


 
Digitman ©   (2005-11-08 13:02) [9]


> VariantClear(varGroup);


это что за беда ?

процедура VariantClear() принимает параметром отнюдь не OleVariant-значение , а TVarData-значение !


 
Набережных С. ©   (2005-11-08 13:35) [10]


> процедура VariantClear() принимает параметром отнюдь не
> OleVariant-значение , а TVarData-значение !

Это одно и то же.

> EgorovAlex ©

У тебя портится стек, скорее всего из-за неправильных деклараций. Обрати внимание, чтобы все параметры интерфейсных типов были объявлены со спецификаторами const, var или out. Т.е. недопустимо такое:
function SomeFunc(Value: IInterface)
Должно быть как-то так:
(const Value: IInterface), (var Value: IInterface), (out Value: IInterface).

То же касаетсе параметров типа TGUID.

Мне нужно уходить, если что - вечером, если получится.


 
EgorovAlex ©   (2005-11-08 14:23) [11]

To Набережных С.
Спасибо, действительно было не совсем верное описание AdsGetObject
Теперь всё работает как надо.



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

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

Наверх




Память: 0.5 MB
Время: 0.049 c
3-1132298547
syte_ser78
2005-11-18 10:22
2006.01.15
доступ к результату запроса


6-1127747930
pr0t0n
2005-09-26 19:18
2006.01.15
Строку в HTML Документ.


1-1134127864
kvorubin
2005-12-09 14:31
2006.01.15
Как сравнить 2 разных списка разбитых по линиям


14-1135159951
старый маразматик(с)
2005-12-21 13:12
2006.01.15
проблемы с расположением контролов на форме


3-1132313834
Карелин Артем
2005-11-18 14:37
2006.01.15
Numeric... Decimal... А отличия есть в них?