Delphi深度探索:活動目錄開發二
繼上文Delphi深度探索:活動目錄開發一,本文接著介紹活動目錄的開發。
創建或刪除計算機用戶
通過 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';
// 創建計算機對象
OleCheck(AdsGetObject(PWideChar(AdsPath),
IID_IADsContainer, ComputerObj));
// 刪除用戶
ComputerObj.Delete('user', UserName);
// 刷新列表
actOpenWinNT.Execute;
end;
end
查看組中的用戶
通過 WinNT provider ,我們還可以執行各種用戶組的維護任務,比如從組中添加或刪除用戶。下面就來演示如何枚舉組中的用戶并察看用戶相關信息。首先讓下面代碼獲得一個 IADsGroup 對象,然后使用 IADsMember 對象來枚舉 IADsGroup 對象中所有用戶對象,列出不同組中的所有用戶:
var
GroupObj: IADsGroup;
Members: IADsMembers;
AdsPath: WideString;
Enum: IEnumVariant;
TempUserObj: OLEVariant;
UserObj: IADsUser;
TempListObj: TListItem;
Value: LongWord;
begin
// 清空列表
GroupListView.Items.Clear;
// 指定域名路徑
AdsPath := 'WinNT://' + MainFrm.ADSIDomainName.Text +'/' + GroupName;
// 創建組對象
OLECheck(AdsGetObject(PWideChar(AdsPath), IID_IADsGroup,
GroupObj));
// 獲得 members 對象
Members := GroupObj.Members;
// 獲取枚舉對象
Enum := (Members._NewEnum) as IEnumVariant;
// 使用枚舉對象進行查找
while (Enum.Next(1, TempUserObj, Value) = S_OK) do
try
// 保存臨時對象
UserObj := IUnknown(TempUserObj) as IADsUser;
// 創建新的列表項
TempListObj := GroupListView.Items.Add;
// 指定屬性
TempListObj.Caption := UserObj.Name;
except
on E:Exception do
圖 1.113
end;
IADsGroup 接口是用來管理 NT 組信息的接口,而它的 Members 屬性是一個管理組中用戶或 ADSI 對象列表的接口。最后使用 IADsUser 接口變量 UserObj 來獲得 NT 組中的用戶信息。
程序運行結果如圖 1.113 所示。
控制 NT 服務
WinNT provider 還可以用來控制 NT 服務、服務器和工作站 , 下面的代碼遍歷 NT 服務 , 并根據相應的計算機添加服務到相應列表中 :
var
UnknownObject: IUnknown;
Computer: IADsContainer;
ComputerPath: WideString;
Enum: IEnumVariant;
AdsTempObj: OLEVariant;
AdsObj: IADs;
Value: LongWord;
begin
if Item.Caption = '' then
Exit;
// 指定域名路徑
ComputerPath := 'WinNT://' + ADSIDomainName.Text +'/' + Item.Caption;
// 創建計算機對象
OleCheck(ADsGetObject(PWideChar(ComputerPath),
IID_IADsComputer, UnknownObject));
// 獲得計算機容器接口
Computer := UnknownObject as IADsContainer;
// 清空服務視圖列表
ServiceListView.Items.Clear;
// 獲取枚舉對象用于遍歷
Enum := (Computer._NewEnum) as IEnumVariant;
// 用枚舉對象進行查找
while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin
// 保存臨時對象
ADsObj := IUnknown(ADsTempObj) as IADs;
// 如果對象為服務的話 ,添加到視圖中
if AdsObj.Class_ = 'Service' then
AddServiceToList(ADsObj);
end;
end.
要想獲得 NT 服務的信息,需要綁定服務對應的 ADSI 對象, ADSI 提供了 IADsService 對象來維護 NT 服務的信息,下面代碼演示了如何綁定 NT 服務,并顯示服務名:
var
ServiceObj: IADsService;
AdsPath: WideString;
begin
// 指定域名路徑
AdsPath := 'WinNT://' + ComputerName + '/' + ServiceName;
// 獲得服務對象
OLECheck(ADsGetObject(PWideChar(AdsPath),
IID_IADsService, ServiceObj));
// 獲得服務名
lblServiceName.Caption := ' 服務名 : ' + ServiceName;
lblDisplayName.Caption := ' 服務顯示名稱 : ' +
ServiceObj.Get_DisplayName;
要想啟動或停止 NT 服務 , 可以使用 IADsServiceOperations ADSI 對象。同上面一樣需要先綁定到 NT 服務上去,而同前面不一樣的是,這回不是獲得 IADsService ADSI 對象,而是獲得 IADsServiceOperations ADSI 對象:
// 創建計算機對象
OleCheck(AdsGetObject(PWideChar(AdsPath),
IID_IADsServiceOperations, Result));
然后使用 GetServiceObj 函數來綁定到 IADsServiceOperations ADSI 對象上 , 并返回 IADsServiceOperations 接口 :
// 獲得服務對象
ServiceObj := GetServiceObj;
啟動服務需要調用 IADsServiceOperations 接口的 Start 方法:
圖 1.114
// 啟動服務 , Get_Status = 1 表明服務正處于停止狀態
if ServiceObj.Get_Status = 1 then
ServiceObj.Start;
要停止服務需要調用 IADsServiceOperations ADSI 對象的 Stop 方法 , 運行結果如圖 1.114 所示。
結論
毫無疑問,通過 ADSI 目錄服務,調用 WinNT provider 可以更容易實現 NT 的管理功能,但它也是一個龐大的系統,光 Windows 的活動目錄編程參考就有上千頁,說明我們必須花費大量時間才能真正掌握它的精髓。
希望本系列Delphi深度探索—活動目錄開發的內容能夠對讀者有所幫助。
【編輯推薦】