Форум: "WinAPI";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];
ВнизКак преобразовать 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 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.012 c