ADSI无法使用ADsOpenObject打开对象。德尔福

时间:2014-05-15 10:30:52

标签: delphi adsi

我有一个允许使用windows登录信息登录的程序,我试图在用户输入密码时获取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;

因此,当输入的用户名和密码正确时,程序将返回该组的路径 当错误&#39;没有访问&#39;出现。

如果我第一次输入正确的用户名和密码,或者输入错误的用户名和密码数据,它的效果也很好。

问题是当我第二次调用该函数时,它没有像预期的那样工作:

当我运行我的程序时,首先输入错误的密码并调用我的功能&#39; NOT ACCESSED&#39;将按预期显示,但如果我使用正确的密码重新调用该功能,它将返回“未访问”&#39;太

此外,当我运行我的程序并首先输入正确的密码并调用我的函数时,组路径会按预期显示,但是如果我回想起密码错误的函数,它也会返回路径。

看起来我的连接数据已保存,我需要释放内存,但我不知道如何。

任何人都能提供帮助吗?

1 个答案:

答案 0 :(得分:0)

最后,我可以为我的问题找到解决方案,看起来像本文中描述的Microsoft API问题: http://support.microsoft.com/kb/218497

实际上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
         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;
  except
     ShowMessage('NOT ACCESSDE');
  end;
end;