【问题标题】:C++/WinRT: How to get attributes of the current userC++/WinRT:如何获取当前用户的属性
【发布时间】:2020-09-18 01:02:15
【问题描述】:

在线文档与 C++/WinRT 的“基本事实”之间似乎存在巨大的脱节。到目前为止,这是我认为我已经弄清楚的:

#include <winrt/Windows.System.Profile.h>

using namespace winrt;
using namespace winrt::Windows;

// ...

auto userBuf = System::Profile::SystemIdentification::GetSystemIdForPublisher().Id();
hstring userStr;  // = ?  How to get this from userBuf?
auto user = System::User::GetFromId (userStr);
hstring firstName = user.GetPropertyAsync (System::KnownUserProperties::FirstName());
hstring lastName  = user.GetPropertyAsync (System::KnownUserProperties::LastName());

是否有更简单/更好的途径来获取当前用户的属性? 如何从 GetSystemIdForPublisher().Id() 返回的缓冲区中获取 User::GetFromId(_) 所需的 hstring?

我发现我可以从 userBuf.data() 获得一个 uint8_t*,但 userBuf.Length() 是链接器中未解析的外部符号。

另外,我的理解是否正确

System::Profile::SystemIdentification::GetSystemIdForUser(nullptr).Id();

会得到当前用户的ID吗? (假设授予 userSystemId 能力)

【问题讨论】:

  • 如果无法访问IBufferLength()属性,则可能是#include &lt;winrt/Windows.Storage.Streams.h&gt;头文件失败。
  • 谢谢。那确实解决了。 间接包含 #include "winrt/impl/Windows.Storage.Streams.0.h",它声明了模板 struct consume_Windows_Storage_Streams_IBuffer { } 带有 Length() 和 data() 函数。我的搜索只把我带到了那里。 data() 是内联的;长度()不是。这些东西的文档真的很不充分。这一切似乎都很神秘。
  • 它比这更复杂。 Length()IBuffer 接口的真正属性,而 data() 是包装器类型上特定于 C++/WinRT 的实用程序实现。我试图将其记录在IBuffer 文档中,但经过漫长的反复来回,它被埋葬了here。如果你想试试运气,WinRT 文档页面的右上角和底部都有反馈链接。
  • GetSystemIdForUser 不返回用户 ID。它返回系统的 id..
  • 是的,我明白了。我只是有点惊讶,不知何故无法从中获取用户 ID。函数文档暗示存在“当前用户”的一些概念,但无法获取该用户的用户 ID。但是,根据本主题底部的回复,这一切现在都没有实际意义。我已经放弃了 UWP 上下文中“当前用户”的概念。

标签: uwp c++-winrt


【解决方案1】:

您可以使用User 类并调用FindAllAsync 方法来查找当前用户。例如:

Windows::Foundation::IAsyncAction MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
    Windows::Foundation::Collections::IVectorView<Windows::System::User> users = co_await Windows::System::User::FindAllAsync(Windows::System::UserType::LocalUser, Windows::System::UserAuthenticationStatus::LocallyAuthenticated);
    Windows::System::User currentUser = users.GetAt(0);
    IInspectable nameObj = co_await currentUser.GetPropertyAsync(Windows::System::KnownUserProperties::FirstName());
    hstring myname = unbox_value<hstring>(nameObj);
}

当您尝试访问当前用户的属性时,您需要在清单文件中添加 userAccountInformation 功能。

<uap:Capability Name="userAccountInformation"/>

另外,我们可以通过hstring myID = currentUser.NonRoamableId();获取不可漫游的id,然后通过这个id获取当前用户。 NonRoamableId 用于检索设置为当前用户的 User 对象。更多详情可以参考这个official sample

【讨论】:

  • 很遗憾,这并不能回答大部分问题:1 如何从FindAllAsync() 返回的IVectorView 中识别“当前用户” ? 2 NonRoamableId 代表什么? 3NonRoamableId 与从GetSystemIdForUser 返回的Id 有什么关系?
  • 最后一条评论——旁注:GetSystemIdForUser(nullptr).Id() 返回的 Id 值与 User::GetFromId( ID)。这让我在试图找到找到当前用户的解决方案时分心。 FindAllAsync() 正在工作,但对我来说一点也不明显;我终于不得不在这里发布一个问题来发现这个解决方案。
  • 这是一个不太可能发生的情况,但这意味着如果我的应用程序在后台运行,它会得到错误的答案。 // 我仍然感到惊讶的是,WinRT 中没有一个简单的可靠函数来获取拥有该进程的用户的身份——至少是他们的登录 ID 和显示名称。相当于GetUserNameW (_, _)GetUserNameExW (_, _, _)
  • @the 在 UWP 应用模型下,每个进程都在自己的用户帐户下运行。该用户帐户与登录用户的用户帐户不同。出于隔离目的,进程不归登录用户所有。
  • @TheodoreHall User.FindAllAsync 查找正在使用您的应用程序的所有用户。例如,这是针对 Xbox 玩多人游戏的情况。在这种情况下,没有一个用户比其他用户更“最新”。在桌面,当你“切换用户”时,被切换出去的用户并没有使用被切换用户的应用程序,所以 FindAllAsync 不会找到他们..
【解决方案2】:

使用 FindAllUsersAsync 时,IVectorView 中返回的第一个 Windows.System.User 实例(即 GetAt(0))始终是桌面和应用商店应用上的当前用户。正如您所指出的,这将返回散列的“系统 ID”(例如:“/baoL6wJRmZp9cT8+jVByhBekwXOv3ONbzQ/6eMqov0=")。也许有人可以插话,但由于安全性和沙盒要求,我从未能够获得您在登录时键入的人类可读的用户 ID 字符串,类似于 Win32 中的 GetUserName()。我假设这就是您要寻找的。​​p>

【讨论】:

  • 实际上,User::FindAllAsync() 返回的值属于 User 类型,可以使用 user.GetPropertiesAsync() 检索单个用户的可读属性。但在此之前可以工作: * AppxManifest.xml 包功能必须包含 * 运行时用户必须为应用启用“设置 > 隐私 > 帐户信息”。
  • 在 HoloLens 上,我发现如果我将任何过滤器参数传递给 User::FindAllAsync()——即使只是 System::UserType::LocalUser——如果我通过身份验证,该函数返回零用户微软帐户。没有任何过滤,它只返回一个用户[0]
猜你喜欢
  • 2012-04-08
  • 1970-01-01
  • 2023-02-13
  • 2015-06-08
  • 1970-01-01
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多