获取 64 位 Windows 7 的用户帐户名称失败

发布于 2024-10-16 07:10:55 字数 4207 浏览 2 评论 0原文

当我的 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”或简单地“管理员”时,代码的执行方式相同。

        #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); 权限.Assert();

My C# winform application fails to get the (local machine's) user account names when installed on a 64bit Windows 7 machine. It works correctly on 32bit Windows 7, 64bit VIsta, 32 bit Vista and XP.

The code fails on the line "DirectoryEntry admGroup = localMachine.Children.Find..." with the error "System.Runtime.InteropServices.COMException [0x800708ac]. The group name could not be found."

What change can I make to the code to get it to work for 64bit Windows 7 (that also works for all the other operating systems)?

Note 1: The line "DirectoryEntry localMachine = new DirectoryEntry..." correctly gets the machine name.

Note 2: For simplicity, I shortened the strings by substituting in "[APLICATION NAME]." The code performs identically when using "[APLICATION NAME].ResourceAdmin.administrators" or simply "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();
                }
            }
        }

Edit: For a similar question on another blog site it was suggested to add this code right before the "DirectoryEntry" statement that fails. I tried this and it did not help.

System.DirectoryServices.DirectoryServicesPermission
permission = new
System.DirectoryServices.DirectoryServicesPermission(System.Security.Permissions.PermissionState.Unrestricted);
permission.Assert();

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

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

发布评论

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

评论(1

薄凉少年不暖心 2024-10-23 07:10:55

怎么样:

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

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

}

然后看一下这两个类的方法和成员,了解如何使用它们。使用它们比 DirectoryEntry 类容易得多 - 没有 LDAP 字符串。

How about this:

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

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

}

Then take a look at methods and members of the 2 classes to learn how to do stuff with them. It's much easier to use these than the DirectoryEntry class - no LDAP strings.

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