【问题标题】:c++ can't get local user groups by NetUserGetGroups()c++ 无法通过 NetUserGetGroups() 获取本地用户组
【发布时间】:2016-08-22 11:47:48
【问题描述】:

无法弄清楚如何使用所有这些“宽 unicode 字符串”。谁能告诉我我做错了什么?我只想获取所有本地用户组,​​所以我这样做了:

LPBYTE buffer;
DWORD entries, total_entries;
NetUserGetLocalGroups(NULL, L"rovnyart", 0, LG_INCLUDE_INDIRECT, &buffer, MAX_PREFERRED_SIZE, &entries, &total_entries);
LOCALGROUP_USERS_INFO_0 *groups = (LOCALGROUP_USERS_INFO_0 *) buffer;

unsigned int i;
for (i=0; i<entries;i++)
    wprintf(L"%s\n", groups[i].lgrui0_name);

这就是我得到的:

t
╝4╝<╝8╝=╝8╝A╝B╝@╝0╝B╝>╝@╝K╝
╝>╝;╝L╝7╝>╝2╝0╝B╝5╝;╝8╝

Process finished with exit code 0

我的 Windows 语言是俄语,但我创建了一个名为“testgroup1”的组,您可以看到它也显示不正确。

我试过wprintf() - 结果是一样的:(

我做错了什么?

更新:

好的,我更改了代码以符合您的建议。我创建了一个名为“test”的非西里尔字母组并将我的用户放在那里。

这是我的代码:

LPBYTE pBuf = NULL;

NET_API_STATUS nStatus;
DWORD entries, total_entries;
nStatus = NetUserGetLocalGroups(NULL, L"rovnyart", 0, LG_INCLUDE_INDIRECT,  &pBuf, MAX_PREFERRED_LENGTH, &entries, &total_entries);

LOCALGROUP_USERS_INFO_0 *groups = (LOCALGROUP_USERS_INFO_0 *) pBuf;
if (nStatus == 0) {
    unsigned int i;

    for (i = 0; i < entries; i++)
        wprintf(L"%s\n", groups[i].lgrui0_name);


    NetApiBufferFree(pBuf);
}

这是输出:

t
╝4╝<╝8╝=╝8╝A╝B╝@╝0╝B╝>╝@╝K╝
╝>╝;╝L╝7╝>╝2╝0╝B╝5╝;╝8╝

Process finished with exit code 0

【问题讨论】:

  • documentation 中有完整的示例代码。
  • 我注意到您的代码没有检查是否成功,没有将输出归零,而是将-1 传递为prefmaxlen。 (文档示例使用MAX_PREFERRED_LENGTH
  • 至少你做错的一件事是将一个宽字符数组传递给'%s'(它需要一个窄字符指针)。您要么需要使用%S,要么需要使用wprintf。当您修复目前已发现的所有错误时会发生什么?
  • 你真的需要阅读Unicode in the Windows API。西里尔字母与拉丁字符并没有什么不同。两者都在 BMP 中。看来您还应该阅读The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
  • 控制台窗口很可能是这里的问题。它缺乏开箱即用的 Unicode 支持。使用调试器,在wprintf 行上插入断点。缓冲区包含什么?

标签: c++ winapi


【解决方案1】:

感谢所有人,包括对我投反对票的人。我的问题的解决方案是%s 格式说明符。我需要使用%S。我的程序正确输出组名:

wprintf(L"%S\n", groups[i].lgruiu0_name);

虽然此代码在我的 CLion 中高亮显示错误,但出于某种原因它仍然有效。

感谢所有有用的链接。

【讨论】:

  • 这不太可能。 LOCALGROUP_USERS_INFO_0 存储一个宽字符串。 %S 说明符指示 wprintf 将其字符串参数解释为 MBCS(窄)字符串。这是您构建环境中的错误吗?改用 Visual Studio 会得到什么结果?
  • 改回wprintfs(L"%s\n",...)。按照建议的here 使用_setmode 在控制台上打印Unicode。如果您使用MessageBoxW 进行测试,groups[i].lgruiu0_name 可能看起来还不错
  • 我建议使用 MessageBoxW() 作为诊断输出而不是输出到控制台来避免整个混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
相关资源
最近更新 更多