| 導購 | 订阅 | 在线投稿
分享
 
 
 

Delphi深度探索-活动目录开发

2006-11-24 00:50:15  編輯來源:互聯網  简体版  手機版  評論  字體: ||
 
 
  活动目录是 Windows NT 4.0 和 Windows 2000 使用的目录服务。要想使用活动目录服务,需要调用 ADSI( 活动目录服务接口 ) 。 ADSI 是一组以 COM 接口的形式提供目录服务的,程序员可以通过 ADSI 存取四种网络目录结构: WinNT (Microsoft SAM 数据库 ) 、 LDAP ( 轻量目录存取协议 ) 、 NDS (NetWare 目录服务 ) 和 NWCOMPAT (Novell NetWare 3.x) 。

   ADSI 可以使 Windows NT 管理员的工作变得轻松。 ADSI 支持管理员执行一些一般的管理任务,比如添加新用户、管理打印机、安全设定和控制 NT 域。因为 ADSI 使用 COM 接口,任何支持 COM 的编程语言像 Delphi 、 BCB 、 VB 、 VC 等都可以调用 ADSI 。

  
Delphi深度探索-活动目录开发


   图 1.111

   活动目录运行在 Windows NT 4.0 和 Windows 2000 上。客户端程序可以运行在 Windows 95 、 Windows 98 、 Windows NT 4.0 和 Windows 2000 上。为了使用 ADSI ,必须安装 ADSI COM 接口。 ADSI 2.5 SDK 可以从 Microsoft ADSI 网址 [url=http://www.pccode.net]下载"http://www.microsoft.com/adsi 下载 。 SDK 包括文档、在线帮助和很多例子,不过不幸的是这些例子都是针对 VB 和 VC 的,这里我们将演示如何使用 Delphi 调用 ADSI 。

   程序演示

   图 1.111 所示的程序演示了如何调用 WinNT provider 提供的功能。演示程序用来连接到一个域,一旦连接到域,程序将会列出在 PDC 上找到的 NT 的用户和组以及域中的计算机。同时这个程序还演示了如何察看域中计算机上的服务和察看、添加、删除 NT 组中的用户。

   使用 ADSI 控制 Windows NT/2000

   ADSI 可以使我们控制用户、组、计算机、文件共享、打印任务、打印队列和服务等系统资源。要想在 Delphi 中调用 ADSI ,需要引入活动目录类型库,调用菜单 Project | Import Type Library 命令,选择 ActiveDs (Version 1.0) 点确认, Delphi 会生成相应的封装文件。

   绑定 Win NT 目录服务

   连接 Win NT 目录服务就是找到域控制器然后绑定到相应的对象上。绑定可以通过 ADsGetObject 或 ADsOpenObject 函数来实现。 ADsGetObject 函数声明如下:

   function ADsGetObject(lpszPathName: PWideChar; const riid: TIID; out obj): HResult; stdcall; external 'activeds.dll';

   第一个参数是对象的路径名,第二个参数是对象的接口标识符,第三个参数用于返回得到的被请求的接口指针。缺省条件下,函数根据当前用户进行安全认证。

   ADsOpenObject 函数在不同的安全认证机制下绑定 ADSI 对象,它主要是通过调用参数返回的用户名和口令来认证的。函数声明如下:

   function ADsOpenObject(lpszPathName: PWideChar; lpszUserName: PWideChar; lpszPassword: PWideChar; dwReserved: LongInt; const riid: TIID; out obj): HResult; stdcall; external 'activeds.dll';

   第一个参数意义同上,第二、三个参数是调用者提供的用户名和口令,第四个参数是一个保留的 provider 标识,用来确定绑定的认证方法,第五个参数是请求接口的接口标识符,最后一个参数用来返回请求的接口指针。

   第一个函数使用登录用户缺省的信任级别,而第二个函数允许开发者指定特殊的安全信任机制来绑定 ADSI 对象。下面代码演示了两种不同的绑定方式:

   procedure TMainFrm.actOpenWinNTExecute(Sender: TObject);

   var

   UnknownObject: IUnknown;

   DomainPath: WideString;

   Domain: IADsContainer;

   begin

   // 指定域路径

   DomainPath := 'WinNT://' + ADSIDomainName.Text;

   // 如果使用用户登录了信息

   if cbUseLogin.Checked then

   // 使用用户登录的信息创建域对象

   OleCheck(AdsOpenObject(PWideChar(DomainPath),

   PWideChar(ADSIUsername.Text),

   PWideChar(ADSIPassword.Text), 0, IID_IADsContainer,

   UnknownObject));

   else

   OleCheck(ADsGetObject(PWideChar(DomainPath),

   IID_IADsContainer, UnknownObject));

   // 设定域对象

   Domain := UnknownObject as IADsContainer;

   // 从域中获得信息列表

   GetDomainInformation(Domain);

   end;

   下面我们需要声明三个变量 :

   第一个是接口变量 , 用来绑定由指定的对象路径返回的函数。

   UnknownObject: IUnknown;

   第二个参数是 WideString 类型的变量 , 用来在绑定函数中产生一个对象路径。

   DomainPath: WideString;

   第三是一个 IADsContainer 接口类型变量 , 用来保存返回的接口变量。

   Domain: IADsContainer;

   IADsContainer 变量将被用来从指定的 ADSI 对象中获得全部用户、组和计算机。当然也可以使用 IADsDomain 类型的变量,但它不适合枚举域中的子对象。

   下面指定想要获得的对象路径 , 如果域名是 "PRISMA" , 要想获得 ADSI 对象 , 就需要指定路径为 "WinNT://PRISMA" :

   // 设定域名路径

   DomainPath := 'WinNT://' + ADSIDomainName.Text;

   下面代码使用不同的安全认证方式:

   // 如果使用登录信息

   if cbUseLogin.Checked then

   // 使用登录并创建域对象

   OleCheck(AdsOpenObject(PWideChar(DomainPath),

   PWideChar(ADSIUsername.Text),

   PWideChar(ADSIPassword.Text), 0, IID_IADsContainer,

   UnknownObject));

   else

   // 创建域对象

   OleCheck(ADsGetObject(PWideChar(DomainPath),

   IID_IADsContainer, UnknownObject));

   然后我们获取 IADsContainer 指针,以便查询域中的子对象:

   // 获取域对象

   Domain := UnknownObject as IADsContainer;

   最后 , 把 IADsContainer 接口指针作为参数调用来获得域中的子对象 :

   GetDomainInformation(Domain);

   在域中查找

   要想在域中查找子对象 , 可以使用 GetDomainInformation 过程 , 代码如下 :

   // 获取域信息

   procedure TMainFrm.GetDomainInformation(

   Domain: IADsContainer);

   var

   Enum: IEnumVariant;

   ADsTempObj: OLEVariant;

   ADsObj: IADs;

   Value: LongWord;

   begin

   // 清空用户、组和计算机列表

   UserListView.Items.Clear;

   GroupListView.Items.Clear;

   ComputerListView.Items.Clear;

   // 获取枚举对象

   Enum := (Domain._NewEnum) as IEnumVariant;

   // 利用枚举对象查找

   while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin

   // 获得临时对象

   ADsObj := IUnknown(ADsTempObj) as IADs;

   // 如果是用户对象

   if AdsObj.Class_ = 'User' then

   AddUserToList(ADsObj);

   // 如果是组对象

   if AdsObj.Class_ = 'Group' then

   AddGroupToList(ADsObj);

   // 如果是计算机对象

   if AdsObj.Class_ = 'Computer' then

   AddComputerToList(ADsObj);

   end;

   end;

   下面是对程序流程的详细说明,首先获得枚举对象,并赋值给 Enum 变量:

   Enum := (Domain._NewEnum) as IEnumVariant;

   然后利用枚举变量进行查找并把每个子对象赋值给临时的 OLEVariant 对象:

   while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin

   OLEVariant 变量赋值给 ADSI 对象

   ADsObj := IUnknown(ADsTempObj) as IADs;

   获得 ADSI 对象后,开始检查对象类,根据对象类别把 ADSI 分别处理,并把不同 ADSI 对象的属性添加到各自的列表视图中去:

   // 如果是用户对象

   if AdsObj.Class_ = 'User' then

   AddUserToList(ADsObj);

   // 如果是组对象

   if AdsObj.Class_ = 'Group' then

   AddGroupToList(ADsObj);

   // 如果是计算机对象

  
Delphi深度探索-活动目录开发


   图 1.112

   if AdsObj.Class_ = 'Computer' then AddComputerToList(ADsObj);

   运行结果如 图 1.112 所示。

   创建或删除计算机用户

   通过 WinNT provider ,可以创建或删除域中任意一台计算机的用户,要想创建一个域中指定的计算机的用户,需要绑定到指定的计算机上。一旦要绑定到计算机对应的 ADSI 容器对象,就需要调用 Create 方法。容器对象的 Create 方法需要两个参数,一个是要创建的 ADSI 对象的类别,一个是要用来描述 ADSI 对象的名字。调用 Create 方法后会返回新的 ADSI 对象的引用参考,下面代码演示了如何创建一个用户:

   var

   ComputerObj: IADsContainer;

   TempUserObj: IUnknown;

   UserObj: IADsUser;

   PDCName: WideString;

   NewUserName: WideString;

   AdsPath: WideString;

   begin

   // 获取用户信息

   PDCName := InputBox(' 创建新用户 ', ' 请输入域名 : ', '');

   NewUserName := InputBox(' 创建新用户 ', ' 请输入用户名 : ', '');

   // 指定域名路径

   AdsPath := 'WinNT://' + PDCName + ',computer';

   // 创建计算机对象

   OleCheck(AdsGetObject(PWideChar(AdsPath),

   IID_IADsContainer, ComputerObj));

   // 创建新用户

   TempUserObj := ComputerObj.Create('user', NewUserName);

   UserObj := TempUserObj as IADsUser;

   // 设定目录信息

   UserObj.SetInfo;

   // 刷新列表

   actOpenWinNT.Execute;

   删除用户也非常类似 , 只不过不需要创建任何的用户对象 , 可直接调用容器对象 IADsContainer 接口的 Delete 方法 , Delete 方法需要两个参数 , 第一个是要删除的对象类别 , 第二个是对象名称 , 代码示意如下 :

   var

   ComputerObj: IADsContainer;

   PDCName: WideString;

   UserName: WideString;

   AdsPath: WideString;

   begin

   // 获取用户信息

   PDCName := InputBox(' 删除用户 ', ' 请输入域名 ', '');

   UserName := InputBox(' 删除用户 ', ' 请输入要删除的用户名 : ', '');

   if MessageDlg(' 你是否确信要删除用户 : ' +UserName + ' ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then

   begin

   // 指定域名路径

   AdsPath := 'WinNT://' + PDCName + ',computer';

   // 创建计算机对象

  

  [1] [2] 下一页
 
 
 
活动目录是 Windows NT 4.0 和 Windows 2000 使用的目录服务。要想使用活动目录服务,需要调用 ADSI( 活动目录服务接口 ) 。 ADSI 是一组以 COM 接口的形式提供目录服务的,程序员可以通过 ADSI 存取四种网络目录结构: WinNT (Microsoft SAM 数据库 ) 、 LDAP ( 轻量目录存取协议 ) 、 NDS [url=http://www.pccode.net](Net[/url]Ware 目录服务 ) 和 NWCOMPAT (Novell[url=http://www.pccode.net] Net[/url]Ware 3.x) 。 ADSI 可以使 Windows NT 管理员的工作变得轻松。 ADSI 支持管理员执行一些一般的管理任务,比如添加新用户、管理打印机、安全设定和控制 NT 域。因为 ADSI 使用 COM 接口,任何支持 COM 的编程语言像 Delphi 、 BCB 、 VB 、 VC 等都可以调用 ADSI 。 [img]http://edu.pccode.net/article/UploadPic/200636155612778.png[/img] 图 1.111 活动目录运行在 Windows NT 4.0 和 Windows 2000 上。客户端程序可以运行在 Windows 95 、 Windows 98 、 Windows NT 4.0 和 Windows 2000 上。为了使用 ADSI ,必须安装 ADSI COM 接口。 ADSI 2.5 SDK 可以从 Microsoft ADSI 网址 [url=http://www.microsoft.com/adsi][url=http://www.pccode.net]下载[/url]"http://www.microsoft.com/adsi [url=http://www.pccode.net]下载[/url] 。 SDK 包括文档、在线帮助和很多例子,不过不幸的是这些例子都是针对 VB 和 VC 的,这里我们将演示如何使用 Delphi 调用 ADSI 。 程序演示 图 1.111 所示的程序演示了如何调用 WinNT provider 提供的功能。演示程序用来连接到一个域,一旦连接到域,程序将会列出在 PDC 上找到的 NT 的用户和组以及域中的计算机。同时这个程序还演示了如何察看域中计算机上的服务和察看、添加、删除 NT 组中的用户。 使用 ADSI 控制 Windows NT/2000 ADSI 可以使我们控制用户、组、计算机、文件共享、打印任务、打印队列和服务等系统资源。要想在 Delphi 中调用 ADSI ,需要引入活动目录类型库,调用菜单 Project | Import Type Library 命令,选择 ActiveDs (Version 1.0) 点确认, Delphi 会生成相应的封装文件。 绑定 Win NT 目录服务 连接 Win NT 目录服务就是找到域控制器然后绑定到相应的对象上。绑定可以通过 ADsGetObject 或 ADsOpenObject 函数来实现。 ADsGetObject 函数声明如下: function ADsGetObject(lpszPathName: PWideChar; const riid: TIID; out obj): HResult; stdcall; external 'activeds.dll'; 第一个参数是对象的路径名,第二个参数是对象的接口标识符,第三个参数用于返回得到的被请求的接口指针。缺省条件下,函数根据当前用户进行安全认证。 ADsOpenObject 函数在不同的安全认证机制下绑定 ADSI 对象,它主要是通过调用参数返回的用户名和口令来认证的。函数声明如下: function ADsOpenObject(lpszPathName: PWideChar; lpszUserName: PWideChar; lpszPassword: PWideChar; dwReserved: LongInt; const riid: TIID; out obj): HResult; stdcall; external 'activeds.dll'; 第一个参数意义同上,第二、三个参数是调用者提供的用户名和口令,第四个参数是一个保留的 provider 标识,用来确定绑定的认证方法,第五个参数是请求接口的接口标识符,最后一个参数用来返回请求的接口指针。 第一个函数使用登录用户缺省的信任级别,而第二个函数允许开发者指定特殊的安全信任机制来绑定 ADSI 对象。下面代码演示了两种不同的绑定方式: procedure TMainFrm.actOpenWinNTExecute(Sender: TObject); var UnknownObject: IUnknown; DomainPath: WideString; Domain: IADsContainer; begin // 指定域路径 DomainPath := 'WinNT://' + ADSIDomainName.Text; // 如果使用用户登录了信息 if cbUseLogin.Checked then // 使用用户登录的信息创建域对象 OleCheck(AdsOpenObject(PWideChar(DomainPath), PWideChar(ADSIUsername.Text), PWideChar(ADSIPassword.Text), 0, IID_IADsContainer, UnknownObject)); else OleCheck(ADsGetObject(PWideChar(DomainPath), IID_IADsContainer, UnknownObject)); // 设定域对象 Domain := UnknownObject as IADsContainer; // 从域中获得信息列表 GetDomainInformation(Domain); end; 下面我们需要声明三个变量 : 第一个是接口变量 , 用来绑定由指定的对象路径返回的函数。 UnknownObject: IUnknown; 第二个参数是 WideString 类型的变量 , 用来在绑定函数中产生一个对象路径。 DomainPath: WideString; 第三是一个 IADsContainer 接口类型变量 , 用来保存返回的接口变量。 Domain: IADsContainer; IADsContainer 变量将被用来从指定的 ADSI 对象中获得全部用户、组和计算机。当然也可以使用 IADsDomain 类型的变量,但它不适合枚举域中的子对象。 下面指定想要获得的对象路径 , 如果域名是 "PRISMA" , 要想获得 ADSI 对象 , 就需要指定路径为 "WinNT://PRISMA" : // 设定域名路径 DomainPath := 'WinNT://' + ADSIDomainName.Text; 下面代码使用不同的安全认证方式: // 如果使用登录信息 if cbUseLogin.Checked then // 使用登录并创建域对象 OleCheck(AdsOpenObject(PWideChar(DomainPath), PWideChar(ADSIUsername.Text), PWideChar(ADSIPassword.Text), 0, IID_IADsContainer, UnknownObject)); else // 创建域对象 OleCheck(ADsGetObject(PWideChar(DomainPath), IID_IADsContainer, UnknownObject)); 然后我们获取 IADsContainer 指针,以便查询域中的子对象: // 获取域对象 Domain := UnknownObject as IADsContainer; 最后 , 把 IADsContainer 接口指针作为参数调用来获得域中的子对象 : GetDomainInformation(Domain); 在域中查找 要想在域中查找子对象 , 可以使用 GetDomainInformation 过程 , 代码如下 : // 获取域信息 procedure TMainFrm.GetDomainInformation( Domain: IADsContainer); var Enum: IEnumVariant; ADsTempObj: OLEVariant; ADsObj: IADs; Value: LongWord; begin // 清空用户、组和计算机列表 UserListView.Items.Clear; GroupListView.Items.Clear; ComputerListView.Items.Clear; // 获取枚举对象 Enum := (Domain._NewEnum) as IEnumVariant; // 利用枚举对象查找 while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin // 获得临时对象 ADsObj := IUnknown(ADsTempObj) as IADs; // 如果是用户对象 if AdsObj.Class_ = 'User' then AddUserToList(ADsObj); // 如果是组对象 if AdsObj.Class_ = 'Group' then AddGroupToList(ADsObj); // 如果是计算机对象 if AdsObj.Class_ = 'Computer' then AddComputerToList(ADsObj); end; end; 下面是对程序流程的详细说明,首先获得枚举对象,并赋值给 Enum 变量: Enum := (Domain._NewEnum) as IEnumVariant; 然后利用枚举变量进行查找并把每个子对象赋值给临时的 OLEVariant 对象: while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin OLEVariant 变量赋值给 ADSI 对象 ADsObj := IUnknown(ADsTempObj) as IADs; 获得 ADSI 对象后,开始检查对象类,根据对象类别把 ADSI 分别处理,并把不同 ADSI 对象的属性添加到各自的列表视图中去: // 如果是用户对象 if AdsObj.Class_ = 'User' then AddUserToList(ADsObj); // 如果是组对象 if AdsObj.Class_ = 'Group' then AddGroupToList(ADsObj); // 如果是计算机对象 [img]http://www.chinamx.com.cn/Article/UploadFiles/200605/2006530121411982.jpg[/img] 图 1.112 if AdsObj.Class_ = 'Computer' then AddComputerToList(ADsObj); 运行结果如 图 1.112 所示。 创建或删除计算机用户 通过 WinNT provider ,可以创建或删除域中任意一台计算机的用户,要想创建一个域中指定的计算机的用户,需要绑定到指定的计算机上。一旦要绑定到计算机对应的 ADSI 容器对象,就需要调用 Create 方法。容器对象的 Create 方法需要两个参数,一个是要创建的 ADSI 对象的类别,一个是要用来描述 ADSI 对象的名字。调用 Create 方法后会返回新的 ADSI 对象的引用参考,下面代码演示了如何创建一个用户: var ComputerObj: IADsContainer; TempUserObj: IUnknown; UserObj: IADsUser; PDCName: WideString; NewUserName: WideString; AdsPath: WideString; begin // 获取用户信息 PDCName := InputBox(' 创建新用户 ', ' 请输入域名 : ', ''); NewUserName := InputBox(' 创建新用户 ', ' 请输入用户名 : ', ''); // 指定域名路径 AdsPath := 'WinNT://' + PDCName + ',computer'; // 创建计算机对象 OleCheck(AdsGetObject(PWideChar(AdsPath), IID_IADsContainer, ComputerObj)); // 创建新用户 TempUserObj := ComputerObj.Create('user', NewUserName); UserObj := TempUserObj as IADsUser; // 设定目录信息 UserObj.SetInfo; // 刷新列表 actOpenWinNT.Execute; 删除用户也非常类似 , 只不过不需要创建任何的用户对象 , 可直接调用容器对象 IADsContainer 接口的 Delete 方法 , Delete 方法需要两个参数 , 第一个是要删除的对象类别 , 第二个是对象名称 , 代码示意如下 : var ComputerObj: IADsContainer; PDCName: WideString; UserName: WideString; AdsPath: WideString; begin // 获取用户信息 PDCName := InputBox(' 删除用户 ', ' 请输入域名 ', ''); UserName := InputBox(' 删除用户 ', ' 请输入要删除的用户名 : ', ''); if MessageDlg(' 你是否确信要删除用户 : ' +UserName + ' ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then begin // 指定域名路径 AdsPath := 'WinNT://' + PDCName + ',computer'; // 创建计算机对象 [1] [url=http://www.chinamx.com.cn/Article/os/win2003/200605/20060530121411_27207_2.html][2][/url] [url=http://www.chinamx.com.cn/Article/os/win2003/200605/20060530121411_27207_2.html]下一页[/url]
󰈣󰈤
日版宠物情人插曲《Winding Road》歌词

日版宠物情人2017的插曲,很带节奏感,日语的,女生唱的。 最后听见是在第8集的时候女主手割伤了,然后男主用嘴帮她吸了一下,插曲就出来了。 歌手:Def...

兄弟共妻,我成了他们夜里的美食

老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...

 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
王朝网络微信公众号
微信扫码关注本站公众号 wangchaonetcn
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味著赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有