GroupPrincipal 和 SAM PrimaryContext 出现无法解释的 InvalidOperationException

发布于 2024-08-18 14:40:23 字数 1094 浏览 1 评论 0 原文

我试图创建一个像这样的主体:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
GroupPrincipal group = new GroupPrincipal(pc);

group.Name = "Some Group Name";
group.Description = "Some Group Name Description";

group.Save();

但是,当执行代码时,我收到以下异常消息:

System.DirectoryServices.AccountManagement: 该属性对该商店无效 类型。

如果我设置Description属性,上面的代码工作得很好,只是没有组的描述。

我做错了什么吗?

提前致谢。

编辑: 我相信我已经找到了解决这个问题的方法(对于任何可能感兴趣的人)。 可以按照与上述相同的方式创建组:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
GroupPrincipal group = new GroupPrincipal(pc);
group.Save();

现在您创建一个 DirectoryEntry 并将其链接到新创建的组,如下所示:

string path = "WinNT://" + machineName + "/" + group.SamAccountName;
DirectoryEntry dEntry = new DirectoryEntry(path);

这允许访问该组的属性,但我是感兴趣的是描述,所以:

dEntry.Properties["description"].Add("Some Decription");
dEntry.CommitChanges();

那就应该可以了。

I am trying to create a Principal like this:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
GroupPrincipal group = new GroupPrincipal(pc);

group.Name = "Some Group Name";
group.Description = "Some Group Name Description";

group.Save();

However, when the code is executed, I get the following exception message:

System.DirectoryServices.AccountManagement:
Property is not valid for this store
type.

If I do not set the Description property, the above code works perfectly fine, just doesn’t have a description for a group.

Am I doing something wrong?

Thanks in advance.

EDIT:
I believe I have found a work-around for this (for anyone who maybe interested).
A group can be created in the same way as above:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
GroupPrincipal group = new GroupPrincipal(pc);
group.Save();

Now you create a DirectoryEntry and link it to the newly created Group like this:

string path = "WinNT://" + machineName + "/" + group.SamAccountName;
DirectoryEntry dEntry = new DirectoryEntry(path);

This allows access to the Properties of that group, but the one I was interested in is Description, so:

dEntry.Properties["description"].Add("Some Decription");
dEntry.CommitChanges();

And that should do it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流心雨 2024-08-25 14:40:23

答案已重写

我已经得到了您的答案,但您可能不太喜欢它。互联网上的信息很少,但在代码中,这是可以解释的:

  • 当您创建 GroupPrincipal,一个 上下文已添加到其中。这个Context内部是一个隐藏类型:SAMStoreCtx,它继承自一个抽象类型StoreCtx;
  • 您调用的 GroupPrincipal 上的每个属性都将调用 IsValidProperty,它是 SamStoreCtx 的内部成员;
  • 但是,它不会对 Name 属性执行此操作;
  • 在 SAMStoreCtx 内部,有一段代码如下(Reflector 输出):

    内部覆盖 bool IsValidProperty(Principal p, string propertyName)
    {
        ObjectMask 无 = ObjectMask.None;
        if (!ValidPropertyMap.TryGetValue(propertyName, out none))
        {
            返回假;
        }
        if ((MaskMap[p.GetType()] & none) <= ObjectMask.None)
        {
            返回假;
        }
        返回真;
    }
    
  • 仔细查看该代码(我花了一些时间),您就会发现该错误。使用 and 运算符将位标志与 none 进行比较的行将始终生成 ObjectMask.None。因此,第二个 if 语句始终为真
  • 当该方法返回 false 时,调用代码(Description 的属性设置器)将引发异常。

我相信这是 Microsoft 库中的一个错误。它仅发生在 SAMStoreCtx 中。也许这是故意的,但因为代码在那里但总是返回 false 让我相信程序员打算使用 or 运算符。使用 DisplayName 等其他属性检查我的发现会引发与预期相同的异常。

您可以联系 Microsoft 询问此问题并向他们展示此主题。我还没有检查过 .NET 4.0 的新测试版,它们的显示可能会有所不同。您可以通过下载 Reflector 并加载相关的 .NET 程序集来亲自检查这一点。

编辑:我已为您联系 Microsoft 并通过 connect.microsoft 报告了该错误.com 这里。如果您愿意,可以关注该问题。

Answer rewritten

I've got your answer, but you may not really like it. The information on the internet is scarce, but in code, it is explainable:

  • When you create your GroupPrincipal, a Context is added to it. This Context is internally of a hidden type: SAMStoreCtx, which inherits from an abstract type StoreCtx;
  • Each property on the GroupPrincipal that you call will call IsValidProperty, an internal member of SamStoreCtx;
  • However, it doesn't do so for the Name property;
  • Inside SAMStoreCtx, there's a piece of code that looks as follows (Reflector output):

    internal override bool IsValidProperty(Principal p, string propertyName)
    {
        ObjectMask none = ObjectMask.None;
        if (!ValidPropertyMap.TryGetValue(propertyName, out none))
        {
            return false;
        }
        if ((MaskMap[p.GetType()] & none) <= ObjectMask.None)
        {
            return false;
        }
        return true;
    }
    
  • Look closely at that code (it took me a moment) and you'll spot the bug. The line comparing a bit flag to none using the and-operator will always result in ObjectMask.None. The second if-statement is therefor always true.
  • The calling code (the Property Settor of Description) throws an exception when this method returns false.

I believe this to be a bug in the Microsoft library. It only happens with the SAMStoreCtx. Perhaps it is on purpose, but because the code is there but always returns false makes me believe the programmers intended the use of the or-operator instead. Checking my findings with other properties like DisplayName throws the same exception as expected.

You can contact Microsoft about this and show them this thread. I haven't checked the new betas of .NET 4.0 which might show up differently. You can check this for yourself by downloading Reflector and loading the relevant .NET assembly.

EDIT: I've contacted Microsoft for you and reported the bug through connect.microsoft.com here. You can follow the issue there if you like.

旧城空念 2024-08-25 14:40:23

您可以使用 GetUnderlyingObject 获取该组的 DirectoryEntry,而不是搜索它。

var newGroup = new GroupPrincipal(context, groupName);

// You must save first           
newGroup.Save();

var entry = (DirectoryEntry) newGroup.GetUnderlyingObject();

entry.Properties["description"].Add(description);
entry.CommitChanges(); 

You can use the GetUnderlyingObject to get the DirectoryEntry for the group instead of searching for it.

var newGroup = new GroupPrincipal(context, groupName);

// You must save first           
newGroup.Save();

var entry = (DirectoryEntry) newGroup.GetUnderlyingObject();

entry.Properties["description"].Add(description);
entry.CommitChanges(); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文