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

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]
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有