Не удается получить имена учетных записей пользователей для 64-разрядной версии Windows 7

Моему приложению C# winform не удается получить имена учетных записей пользователей (локальной машины) при установке на 64-битную машину с Windows 7. Он корректно работает на 32-битной Windows 7, 64-битной VIsta, 32-битной Vista и XP.

Сбой кода в строке «DirectoryEntry admGroup = localMachine.Children.Find…» с ошибкой «System.Runtime.InteropServices.COMException [0x800708ac]. Не удалось найти имя группы».

Какие изменения я могу внести в код, чтобы заставить его работать на 64-битной Windows 7 (это также работает для всех других операционных систем)?

Примечание 1. Строка «DirectoryEntry localMachine = new DirectoryEntry…» правильно получает имя компьютера.

Примечание 2. Для простоты я сократил строки, заменив «[ИМЯ ПРИЛОЖЕНИЯ]». Код работает одинаково при использовании «[ИМЯ ПРИЛОЖЕНИЯ].ResourceAdmin.administrators» или просто «administrators».

        #region Get Windows User Accounts
        private void GetWindowsUser()
        {
            DataSet dsWindowsUser = null;
            try
            {
                //Retrieve machine name.
                DirectoryEntry localMachine = new DirectoryEntry([APLICATION NAME].ResourceAdmin.WiinNT + Environment.MachineName);

//CODE FAILS ON THE NEXT LINE
                DirectoryEntry admGroup = localMachine.Children.Find([APLICATION NAME].ResourceAdmin.administrators, [APLICATION NAME].ResourceAdmin.group);
             // DirectoryEntry admGroup = localMachine.Children.Find("administrators", "group");  //TEST CODE           

                object adminmembers = admGroup.Invoke([APLICATION NAME].ResourceAdmin.members, null);
             // object adminmembers = admGroup.Invoke("members", null);  //TEST CODE    

                DirectoryEntry userGroup = localMachine.Children.Find([APLICATION NAME].ResourceAdmin.Users, [APLICATION NAME].ResourceAdmin.group);
                object usermembers = userGroup.Invoke([APLICATION NAME].ResourceAdmin.members, null);

                //Create datatable to store windows user.
                DataTable dtWindowsUser = new DataTable();
                DataRow drow;

                //Create datatable to add user
                DataColumn myDataColumn;
                myDataColumn = new DataColumn();
                myDataColumn.DataType = Type.GetType("System.String");
                myDataColumn.ColumnName = "WindowsUser";

                //Add column to datatable
                dtWindowsUser.Columns.Add(myDataColumn);

                //Retrieve each user name.
                foreach (object groupMember in (IEnumerable)adminmembers)
                {
                    DirectoryEntry member = new DirectoryEntry(groupMember);
                    if (!(member.Name == "admin" || member.Name == "Domain Admins"))
                    {
                        drow = dtWindowsUser.NewRow();
                        drow["WindowsUser"] = member.Name;

                        //Add row to datatable
                        dtWindowsUser.Rows.Add(drow);
                    }
                }
                foreach (object groupMember in (IEnumerable)usermembers)
                {
                    DirectoryEntry member = new DirectoryEntry(groupMember);
                    if (!(member.Name == "ACTUser" || member.Name == "ASPNET" || member.Name == "Domain Users" || member.Name == "Authenticated Users" || member.Name == "INTERACTIVE" || member.Name == "SQLDebugger"))
                    {
                        drow = dtWindowsUser.NewRow();
                        drow["WindowsUser"] = member.Name;

                        //Add row to datatable
                        dtWindowsUser.Rows.Add(drow);
                    }
                }
                dsWindowsUser = new DataSet();
                dsWindowsUser.Tables.Add(dtWindowsUser);

                //Add User to database
                objAdminDAO.AddUpdateUserInfo(dsWindowsUser);
            }
            catch (Exception ex)
            {
                BusinessObject.Logger.Logger.Log(ex);
            }
            finally
            {
                if (!(dsWindowsUser == null))
                {
                    dsWindowsUser.Dispose();
                }
            }
        }

Редактировать: Для аналогичного вопроса на другом сайте блога было предложено добавить этот код прямо перед оператором "DirectoryEntry", который не работает. Я пробовал это, и это не помогло.

Разрешение System.DirectoryServices.DirectoryServicesPermission = новое разрешение System.DirectoryServices.DirectoryServicesPermission(System.Security.Permissions.PermissionState.Unrestricted); разрешение.Утвердить();


person Frederick    schedule 08.02.2011    source источник


Ответы (1)


Как насчет этого:

using(PrincipalContext ctx = new PrincipalContext(ContextType.Machine)) {

      UserPrincipal userPrincipal = new UserPrincipal(ctx, "myNewAccount", "myPass", true);

}

Затем взгляните на методы и члены двух классов, чтобы узнать, как с ними работать. Их гораздо проще использовать, чем класс DirectoryEntry — никаких строк LDAP.

person dexter    schedule 08.02.2011
comment
да, это было и мое предложение, чтобы избавиться от кода ldap и заменить его на DirectoryServices, это намного проще в использовании - person Alex; 08.02.2011
comment
@chad: мне трудно включить ваше предложение в мой код. Что мне делать с myNewAccount и myPass? Я оставлю эти строки как есть? - person Frederick; 08.02.2011