c# - 从 __ComObject 获取可调用方法

标签 c# active-directory invoke comobject

我正在优化一些用于查询 Active Directory 的代码。其中一种方法获取自特定更新以来发生更改的所有 AD 用户,由目录条目的 uSNCreated 属性确定。本质上,它相当于执行 C# 操作:

select * from PrincipalSearcher where 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 - __ComObject 只是我可以得到的可见“HighPart”或“LowPart”似乎没有公开它们(即使我可以调用使用 InvokeMember())

有办法解决这个问题吗,还是该承认失败了?

最佳答案

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

关于c# - 从 __ComObject 获取可调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46736036/

相关文章:

c# - .NET 服务器垃圾回收和对象生命周期

c# - Pivot Double Click - Show Detail 事件

asp.net - 单元测试 - 用户帐户

c# - 委托(delegate)名单和调用

Python调用和控制台输出问题

Java:带有 Callables 的 ExecutorService:invokeAll() 和 future.get() - 结果顺序正确吗?

c# - 将 DateTime 发送到默认序列化的 WCF 服务

c# - 当我尝试从 C# Windows 应用程序运行 ssis 包时,我收到一条失败消息。

c# - 如何在 C# 中从 Active Directory 获取自定义字段?

active-directory - DirectorySearcher 用户搜索过滤器无效