views:

63

answers:

2

I have some code that is looking up group memberships from local groups on a machine. For each member, it tries to load some information about the user (eg. find a group and get the names of each of its members).

The code:

using (DirectoryEntry machine = new DirectoryEntry("WinNT://" + Environment.MachineName + ", Computer"))
{
    using (DirectoryEntry group = machine.Children.Find(groupName, "group"))
    {
        object members = group.Invoke("members", null);

        foreach (object groupMember in (IEnumerable) members)
        {
            using (DirectoryEntry member = new DirectoryEntry(groupMember))
            {
                member.RefreshCache();
                string name = member.Name;
                // <code snipped>
            }
        }
    }
}

The code works fine most of the time, but for some group members, it throws a FileNotFoundException when the RefreshCache() method is thrown:

System.IO.FileNotFoundException: 
    The filename, directory name, or volume label syntax is incorrect.
    (Exception from HRESULT: 0x8007007B)
at System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.GetInfo()
at System.DirectoryServices.DirectoryEntry.RefreshCache()
at GroupLookup.GetLocalGroupMembership(String groupName)

What is causing the FileNotFoundException (and what file is it looking for)?

+1  A: 

The file-not-found error is commonly used in the Win32 API as a "resource not found" error. So, it's returned for things like missing Registry keys, or - in this case - an ADSI node.

I am definitely not an ADSI expert, but your first call to the DirectoryEntry constructor seems to be using an invalid path style according to MSDN. I believe you'd need the domain name before the machine name.

Update:

Noticed this on another MSDN page: "GetInfo cannot be used for groups that contain members that are wellKnown security principals in the WinNT scope."

Given the stack trace, it seems like this may be causing the problem.

Stephen Cleary
The machine is part of a domain, but I am querying the local groups information (the local groups may contain domain items though). I thought that I would not need the domain name in this case.
adrianbanks
In this case, I would try the `WinNT://<server>` path, without specifying the `computer` type.
Stephen Cleary
I looked at it with fresh eyes. Check out the answer update (which is really a totally different answer), and see if that helps.
Stephen Cleary
A: 

I didn't get to the bottom of what was causing the FileNotFoundException, although I suspect it was to do with the group set-up - the groups had both local and domain users in them.

Because I only needed the users' names and SIDs, and these were already present on the DirectoryEntry, I solved this issue by not calling the RefreshCache method. This lets the code execute without an exception.

adrianbanks