从__ComObject获取可调用方法



我正在优化一些用于查询Active Directory的代码。其中一个方法获取自特定更新以来更改的所有AD用户,该更新由目录项的uSNCreated属性确定。本质上,它做的是C#等价物:

从PrincipalSearcher中选择*,其中uSNCreated>somevalue

代码是(或多或少):

public IEnumerable<UserPrincipal> GetUpdatedUsers(string samAccountName, long lastUsnChanged)
{
using (var context = new PrincipalContext(ContextType.Domain))
using (var userSearcher = new PrincipalSearcher(new UserPrincipal(context)))
{
var items = userSearcher.FindAll().Cast<UserPrincipal>();
return items.Where(x => GetUsnChanged(x) > lastUsnChanged).ToArray();
}
} 
private static long GetUsnChanged(Principal item)
{
var de = item.GetUnderlyingObject() as DirectoryEntry;
if (de == null)
return 0;
if (!de.Properties.Contains("uSNCreated"))
return 0;
var usn = de.Properties["uSNCreated"].Value;
var t = usn.GetType();
var highPart = (int)t.InvokeMember("HighPart", BindingFlags.GetProperty, null, usn, null);
var lowPart = (int)t.InvokeMember("LowPart", BindingFlags.GetProperty, null, usn, null);
return highPart * ((long)uint.MaxValue + 1) + lowPart;
}

现在,这段代码确实有效,但对InvokeMember()的重复调用是缓慢的。我想做的是获得对HighPart和LowPart属性的引用,这样我就可以反复调用它们,而不需要每次调用InvokeMember()时都"重新发现"它们。

我想我可以做一些类似的事情

static PropertyInfo highProp = highProp
?? t.GetProperty("HighPart", BindingFlags.GetProperty);
highPart = (int)highProp.GetValue(usn);

不幸的是,t.GetProperty()总是返回null。查看GetProperties()、GetMethods()和GetMembers()返回的结果,即使使用BindingFlags.NonPublic,似乎也没有可见的"HighPart"或"LowPart"。__ComObject似乎根本没有公开它们(尽管我可以使用InvokeMember()调用

有没有办法解决这个问题,或者是时候承认失败了?

System.DirectoryServices.AccountManagement命名空间中的类是为在简单情况下使用而设计的,例如,您需要查找用户或组。这些类存在已知的性能问题。我建议使用DirectorySearcher或LdapConnection/SearchRequest。在这种情况下,您可以在服务器上而不是在客户端上过滤对象,这将显著提高性能并减少通过网络发送的数据。以下是使用DirectorySearcher查找所有用户的示例:从AD域获取所有用户在您的情况下,过滤器看起来像(&(objectClass=user)(uSNCreated>=x+1)),其中x是您的最后一个usn。请注意,如果您跟踪具有usnCreated属性的对象,您将只获得自上次usn以来创建的用户。要跟踪更改,请使用我们更改的属性

相关内容

  • 没有找到相关文章

最新更新