简体   繁体   English

如何使用C ++ / CX在UWP应用中查找当前用户的名称?

[英]How to find the current user's name in a UWP app using C++/CX?

Unlike C#, there does not appear to be a straight forward way to get the currently logged in user's name in a UWP application in C++. 与C#不同,在C ++中的UWP应用程序中似乎没有一种简单的方法来获取当前登录的用户名。 One of the Xbox Live certification requirements involves getting this information and displaying it on the main menu, and this game was written in C++ before Windows 10 was even a thing so this is one of the challenges I'm experiencing while porting it over. Xbox Live认证要求中的一项要求涉及获取此信息并将其显示在主菜单上,并且该游戏是在Windows 10甚至还没出现之前就用C ++编写的,因此这是我在移植它时遇到的挑战之一。

This is the function that I have attempted to write in order to accomplish the task. 这是我尝试编写以完成任务的功能。 What I get is an empty string. 我得到的是一个空字符串。

int get_user_name( char* username )
{
    auto users = User::FindAllAsync();
    auto event1 = CreateEventEx( NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE );

    /* Wait for asynchronous procedure to finish */
    for(;;)
    {
        if( users->Status == Windows::Foundation::AsyncStatus::Completed )
            break;

        WaitForSingleObjectEx( event1, 100, FALSE );
    }

    CloseHandle( event1 );

    auto results = users->GetResults();
    if( results->Size < 1 )
    {
        strcpy( username, "Nil" );
        return 1;
    }

    for( int i = 0; i < results->Size; i++ )
    {
        User^ user = results->GetAt(i);
        auto name = user->GetPropertyAsync( KnownUserProperties::DisplayName );

        auto event2 = CreateEventEx( NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE );
        for(;;)
        {
            if( name->Status == Windows::Foundation::AsyncStatus::Completed )
                break;

            WaitForSingleObjectEx( event2, 100, FALSE );
        }
        CloseHandle( event2 );

        Platform::Object^ object = name->GetResults();
        std::wstring wstr = object->ToString()->Data();

        //setup converter
        typedef std::codecvt_utf8<wchar_t> convert_type;
        std::wstring_convert<convert_type, wchar_t> converter;

        //use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
        std::string converted_str = converter.to_bytes( wstr );

        strcpy( username, converted_str.c_str() );
    }

    return 1;
}

Now, I'm aware that this isn't the most well written function, but the main thing is getting it working for the time being. 现在,我知道这不是写得最好的函数,但是主要的事情是暂时使它工作。

This is the absolute best I could come up with, and countless days of googling hasn't yielded anything helpful so far, minus a very complicated C++ sample I found on GitHub here (all the asynchronous stuff makes it more confusing for me): https://github.com/Microsoft/Windows-universal-samples/blob/master/Samples/UserInfo/cpp/Scenario1_FindUsers.xaml.cpp#L33 这是我能想到的绝对最好的选择,到目前为止,无数次谷歌搜索没有产生任何帮助,减去了我在GitHub上发现的一个非常复杂的C ++示例(所有异步内容对我来说都更加令人困惑): https ://github.com/Microsoft/Windows-universal-samples/blob/master/Samples/UserInfo/cpp/Scenario1_FindUsers.xaml.cpp#L33

Any ideas? 有任何想法吗? Thanks. 谢谢。

To understand the whole scenario. 了解整个场景。 There are two things that you can try. 您可以尝试两种方法。

You can learn from this page https://docs.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-in-cpp-universal-windows-platform-apps#creating-a-chain-of-tasks to understand how to use lambda and task chain to create the async action If it is too complex, you can consider "co_await" as the alternative way. 您可以从此页面中学习https://docs.microsoft.com/zh-cn/windows/uwp/threading-async/asynchronous-programming-in-cpp-universal-windows-platform-apps#creating-a-chain-任务 ,了解如何使用lambda和任务链创建异步操作如果操作太复杂,则可以考虑使用“ co_await”作为替代方法。 Here are some related info: 以下是一些相关信息:

  1. https://blogs.msdn.microsoft.com/vcblog/2016/04/04/using-c-coroutines-to-simplify-async-uwp-code/ https://blogs.msdn.microsoft.com/vcblog/2016/04/04/using-c-coroutines-to-simplify-async-uwp-code/

  2. https://channel9.msdn.com/Events/Build/2016/P489 https://channel9.msdn.com/Events/Build/2016/P489

I've created a simple test code to simplify the whole screnario: 我创建了一个简单的测试代码来简化整个场景:

Step 1: Add the following header file(Then add /await to compile command): 步骤1:添加以下头文件(然后添加/ await来编译命令):

#include <pplawait.h>
#include <experimental\resumable>

Step 2: Chick to choose "User Account Information" from Capbility tap in packagemanifest 步骤2:从packagemanifest中的Capability(功能)中选择“ User Account Information(用户帐户信息)”

Step 3: Write the following test code in cpp: 步骤3:在cpp中编写以下测试代码:

task<void> FindUserCPlusTest::MainPage::test()
{
IVectorView<Windows::System::User ^> ^users = co_await User::FindAllAsync();
auto user = users->GetAt(0);
auto name = co_await user->GetPropertyAsync(KnownUserProperties::DisplayName);
auto displayname=safe_cast<String^>(name);
}

Step 4:Write the following code in .h 步骤4:在.h中编写以下代码

concurrency::task<void> test();

Step 5:Put your method in any place and debug it When debugging you will be able to see the default user's display name. 步骤5:将您的方法放在任何地方并对其进行调试在调试时,您将能够看到默认用户的显示名称。 You can get started from this simple test. 您可以从这个简单的测试开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM