Windows 选择用户,服务帐户或群组对话框:
通过API提供给第三方开发人员?
是否有“AD浏览器”常用对话框?
答案 0 :(得分:6)
如果您正在寻找.NET解决方案,我们已在https://github.com/Tulpep/Active-Directory-Object-Picker创建了一个NuGet。
它基于此项目https://adui.codeplex.com/,但已针对x64计算机进行了更新。
答案 1 :(得分:4)
示例伪代码:
String SelectUsers(HWND hwndParent, IList<String> usersLdapPaths)
{
IDsObjectPicker objPicker;
IDataObject objData;
PDSOP_INIT_INFO pInfo;
LPWSTR[0..2] attr;
HRESULT hr;
/*
Returns the LDAP path to the selected user, e.g.:
LDAP://stackoverflow.com/CN=Ian Boyd,OU=Stack Users,DC=stackoverflow,DC=com
usersLdapPaths can be null.
If not null then the user can mutli-select users,
and the selected user's LDAP paths will be returned in usersLdapPaths
(with the function result containing just the first user)
If the user cancels the dialog, then the result (and usersLdapPaths ) will be empty
*/
Result := '';
objPicker = CreateComObject(CLSID_DsObjectPicker) as IDsObjectPicker;
System.New(pInfo);
try
{
ZeroMemory(pInfo, SizeOf(DSOP_INIT_INFO));
pInfo.cbSize = SizeOf(DSOP_INIT_INFO);
pInfo.pwzTargetComputer = nil; //local computer
pInfo.cDsScopeInfos := 1;
System.New(pInfo.aDsScopeInfos);
try
{
ZeroMemory(pInfo.aDsScopeInfos, SizeOf(DSOP_SCOPE_INIT_INFO));
pInfo.aDsScopeInfos.cbSize = SizeOf(pInfo.aDsScopeInfos);
pInfo.aDsScopeInfos.flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN; //or DSOP_SCOPE_TYPE_TARGET_COMPUTER;
pInfo.aDsScopeInfos.flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_LDAP;
pInfo.aDsScopeInfos.FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
pInfo.aDsScopeInfos.FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
if (UsersLdapPaths != null)
pInfo.flOptions = DSOP_FLAG_MULTISELECT;
pInfo.cAttributesToFetch := 3;
attr[0] = "description";
attr[1] = "name";
attr[2] = "fullName";
pInfo.apwzAttributeNames = @attr;
hr = objPicker.Initialize(pInfo);
OleCheck(hr);
hr = objPicker.InvokeDialog(hwndParent, objData);
OleCheck(hr);
//the result is false if the user cancelled the dialog
if hr = S_FALSE then
return '';
return ReadAttributes(objData, UsersLdapPaths);
}
finally
{
System.Dispose(pInfo.aDsScopeInfos);
}
}
finally
{
Dispose(pInfo);
}
}
辅助函数(我不打算从一种伪代码语言转换为另一种伪代码语言):
function TActiveDirectory.ReadAttributes(ADataObject: IDataObject; AValues: TStrings): string;
var
fmtIn: TFormatEtc;
stgOut: TStgMedium;
pSelList: PDS_SELECTION_LIST;
i: Integer;
path: string;
// x: LongWord;
// pVar: POleVariant;
items: PDsSelectionArray;
begin
Result := '';
if Assigned(AValues) then
AValues.Clear;
if not Assigned(ADataObject) then
Exit;
stgOut.tymed := TYMED_HGLOBAL;
fmtIn.tymed := TYMED_HGLOBAL;
fmtIn.cfFormat := RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
fmtIn.dwAspect := DVASPECT_CONTENT;
fmtIn.lindex := -1;
if (ADataObject.GetData(fmtIn, stgOut) <> S_OK) then
Exit;
pSelList := GlobalLock(stgOut.hGlobal);
try
if pSelList.cItems > 0 then
items := PDsSelectionArray(@pSellist.aDsSelection)
else
items := nil;
for i := 0 to pSelList^.cItems-1 do
begin
// path := TDsSelectionArray(pSellist.aDsSelection)[i].pwzADsPath;
path := items[i].pwzADsPath;
if Assigned(AValues) then
AValues.Add(path);
if Result = '' then
Result := path;
{ Result := pSelList^.aDsSelection[i].pwzName+' ('+pSelList.aDsSelection[i].pwzADsPath+')';
AValues.Add(Result);
AValues.Add(' Class: '+pSelList^.aDsSelection[i].pwzClass); //"user"
AValues.Add(' UPN: '+pSelList^.aDsSelection[i].pwzUPN ); //e.g. "ian@stackoverflow.com"
pVar := pSelList^.aDsSelection[i].pvarFetchedAttributes;
for x := 0 to pSelList^.cFetchedAttributes-1 do
begin
AValues.Add(' '+VarToStr(pVar^));
if x < pSelList^.cFetchedAttributes then
Inc(pVar);
end;}
end;
finally
GlobalUnlock(stgOut.hGlobal);
end;
end;
答案 2 :(得分:0)