twhall Ответов: 0

C++/winrt: как получить атрибуты текущего пользователя


[Полное раскрытие информации: я опубликовал аналогичный вопрос (та же тема) на "другом форуме разработчиков" и получил там ответ, который не совсем удовлетворителен. Я немного перефразирую этот вопрос здесь в надежде, возможно, получить что-то другое.]

Я ищу эквивалент UWP C++/WinRT функций Windows, отличных от UWP, чтобы получить идентификатор входа и отображаемое имя для владельца текущего процесса:

GetUserNameW (_, _);
GetUserNameExW (_, _, _);


Что я уже пробовал:

В C++/WinRT я нашел эти две функции, но нет никакого очевидного способа получить от IBuffer sysId для текущего пользователя, возвращаемого первой функцией, к hstring userId, требуемому второй. Свойства, которые мне нужны, требуют пользовательского объекта из идентификатора пользователя hstring:

#include <winrt/Windows.System.h>
#include <winrt/Windows.System.Profile.h>
using namespace winrt;
using namespace winrt::Windows;

IBuffer sysId = // "pass null into this ... which gets the current user's ID."
    System::Profile::SystemIdentification::GetSystemIdForUser(nullptr).Id();
hstring userId;  // = ?  Can't get here from there
System::User user = System::User::GetFromId (userId);
// Once I have the User object, I can get the properties I seek


Сначала это казалось достаточно простым, но, очевидно, нет никакого способа получить требуемый идентификатор пользователя из sysId. (До сих пор это никак не задокументировано и не предложено. Я пробовал разные стратегии, но ни одна из них не сработала.)

Вместо этого мне посоветовали использовать эту функцию, чтобы получить список пользователей. По умолчанию (без аргументов) извлекается весь список. Аргументы ограничивают результаты LocalUser, LocallyAuthenticated, и пользователь, которого я ищу, должен быть возвращен в векторном элементе 0:

Windows::Foundation::Collections::IVectorView<Windows::System::User> users =
    co_await Windows::System::User::FindAllAsync (
        Windows::System::UserType::LocalUser,
        Windows::System::UserAuthenticationStatus::LocallyAuthenticated);


У меня есть несколько проблем с этим:

* В HoloLens 2, прошедшем проверку подлинности через учетную запись Microsoft, эта функция вернула 0 пользователей. Мне пришлось опустить не только LocallyAuthenticated, но и (что удивительно) ограничение LocalUser, чтобы получить непустой результат.

* В настольной системе, через "Switch user", может быть несколько одновременных LocallyAuthenticated LocalUsers. Будучи "социально дистанцированным" и работая из дома, я не могу пригласить другого пользователя войти в мою машину локально для тестирования при этом условии. Когда я поднял этот вопрос на "другом форуме", ответчик сказал, что он попробовал его, и "он просто вернул текущего пользователя вместо всех них". вероятно, все в порядке, но это означает, что в маловероятном случае, если мое приложение останется работать в фоновом режиме, оно может получить неправильный ответ. Если он запрашивает это только при инициализации программы, есть крошечный, но ненулевой шанс получить неправильный ответ.

* Это все еще означает, что мне нужен другой код для настольного приложения (с указанием LocalUser, LocallyAuthenticated) по сравнению с приложением HoloLens (без этих спецификаций). Не такая уж большая проблема, потому что вариант UWP C++/WinRT в основном ориентирован на HoloLens 2; у нас уже есть вариант без UWP, который счастливо работает на рабочем столе. Но все же было бы предпочтительнее иметь код UWP, который также работает на рабочем столе, по крайней мере для некоторой разработки и тестирования.

Другая стратегия пришла ко мне: я могу выполнить итерации через список пользователей, возвращаемых методы findallasync(_, _), получить sysId для каждого, а сравнить с sysId для текущего пользователя (получается путем пропускания nullptr, чтобы GetSystemIdForUser(_).Идентификатор()). Я попробовал это сделать, но ни один из идентификаторов системы пользователя не сравнялся с идентификатором, полученным с помощью nullptr.

C++/WinRT UWP кажется более запутанным и загадочным, чем это должно быть. Я просто хочу идентифицировать пользователя, который запускает программу. У программы есть аспект сотрудничества; приятно отмечать сотрудников с какой-то идентичностью.

0 Ответов