如何在Windows10上获取设备平台

How to get the device platform on Windows 10

由于一个发布的二进制文件将 运行 在 pc、xbox 和手机上,我需要一种在 运行 时间获取设备类型的方法。

通过ApiInformation检查当前的类型、方法等是可行的,但我相信应该有更可靠的方法。

目前(使用 2015 年 3 月 23 日发布的预览工具)没有简单的方法可以做到这一点,除了(如您提到的)使用 ApiInformation 方法来检测实现的东西仅存在于您所追求的特定平台上。

如果有一些帮手来做这件事就好了,如果 none 在最终工具中,我相信社区中有帮助的人会创建一些工具。

但是,有一个很好的理由不这样做,因为它鼓励对设备进行广泛的假设。

如果可以说 "Am I running on a phone?" 那么如果你得到回应 'Yes' 那么就很容易假设该设备的可能性但不是全部 phone s 具有相同的功能。
phones 和小型平板电脑似乎都会有 Windows 10 的 "mobile" 版本。如果你能说 "am I the 'mobile' version?" 那么这可能不会回答你所有的问题,你仍然必须检查个人 API 可用性作为廉价平板电脑和高端 phone 可能会有很大的不同。 (设备上包含物理按钮和拨打 phone 电话的能力是两个明显的例子。) 进一步扩展这一点,在许多情况下,您会将不同的平台视为所有平台上都存在的功能。在这种情况下,您的代码最好说 "Is such and such API available?",而不是说 "Am I running on desktop, Xbox or SurfaceHub?".
由于不同物联网设备可用的功能和能力的范围,物联网平台可能会使这个问题进一步复杂化。

在极少数情况下,您想知道您 运行 所在的平台,而不是特定 API 是否可用。希望通过只公开 API 可用性,Microsoft 鼓励开发人员考虑检查他们实际需要的东西,而不是依赖广泛的、可能不完整的设备分类。

就像您不知道您使用的是什么平台或浏览器的 Web 开发一样 运行,您不应该检测平台并假设该设备将因此具有哪些功能,您应该在使用它或在您的应用程序中公开关联的 UI 之前检测您需要的特定功能是否在设备上 supported/enabled。

此外,为了支持 Alan 在他的评论中描述的场景,您可以检查合同而不是特定类型,因为这表示相关功能块。对于 Windows Phone 特定的 API 有一个这样的合同 - 我在此处描述 http://inthehand.com/2015/03/26/determine-if-running-on-windows-phone-from-a-uap-application/ 由于此合同为当前 Windows Phone 应用程序提供了兼容性 APIs,我们现在可以假设它不会在小型平板电脑中实现,因为它们没有这个。显然,由于 OS 或 API 不是最终的,所以这还不是一成不变的。这对于 Windows Phone 来说是一件有用的事情,特别是如果在过渡期间您只想在 WP 设备上交叉推广旧版 WP 应用程序。对于自定义物联网设备,我会在 API 级别检查可用性。

[编辑 7 月 3 日,将 //build-era 信息替换为当前信息]

虽然您可以尝试使用 ApiInformation API 检测 API 来推断您正在使用的设备,但这是一个非常糟糕的解决方案,因为 API 会随着时间的推移添加到设备中。请不要那样做;您未来的自己(或您的替代者 ;-) )会感谢您。

如果您确实需要以编程方式检测您 运行 使用的设备系列(并且在大多数情况下您不需要 ),那么您可以使用AnalyticsInfo.VersionInfo.DeviceFamliy。此 returns 一个没有发布标准值集的字符串,因为设备系列可能随时引入或停用。

如果您想为每个设备系列提供不同的资源(字符串、图像、XAML 文件、HTML 页面等),那么您不需要检测设备系列在代码中;相反,您可以使用 MRT 限定符 DeviceFamily(例如 Logo.DeviceFamily-Mobile.png)。只需确保您 总是 有后备资源(图像、字符串等),以便在应用程序 运行 在您以前从未听说过的设备系列上使用时使用。并且不要陷入假设 "Desktop requires higher-res assets than Mobile" 之类的陷阱,因为这通常是不正确的。

您可以使用特别命名的文件夹指定设备系列独有的资源和视图:(http://www.sharpgis.net/post/2015/04/01/Creating-DeviceFamily-specific-layouts-in-a-Universal-App)。

对于上述 "advertising only same family apps" 场景,您可以将 JSON 或 XML 文件放在该设备系列的文件夹中,并在运行时使用存储 API的。

似乎有一个新的 API 来检测设备系列: Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily

您可以在此处找到更多信息:https://msdn.microsoft.com/en-us/library/windows/apps/dn705767.aspx

更新:

https://msdn.microsoft.com/en-us/library/windows/apps/windows.system.profile.analyticsversioninfo.aspx

我将其用于 phone(手机):

if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile")
{
      // code for phone 
}
else
{
      // other code
}

例子是here

这只是重复之前建议使用 Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily 的答案之一,但我想我会包含完整的代码以供检查:

// ----------------------------------------------------------------------
// IsRunningOnXbox
// Determines whether or not the game is running on an xbox console
bool IsRunningOnXbox()
{
    // Skip if already checked
    static bool bChecked = false;
    static bool bRunningOnXbox = false;
    if (bChecked)
        return bRunningOnXbox;

    // Retrieve the platform device family
    Platform::String^ strVersionInfoDeviceFamily = Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily;
    if (strVersionInfoDeviceFamily != nullptr)
    {
        // Check to see if the device belongs to the xbox family
        std::wstring strDeviceFamily = strVersionInfoDeviceFamily->Data();
        std::transform(strDeviceFamily.begin(), strDeviceFamily.end(), strDeviceFamily.begin(), ::tolower);
        if (strDeviceFamily.find(L"xbox") != std::wstring::npos)
            bRunningOnXbox = true;
    }

    // Check complete
    bChecked = true;

    // Return whether or not the host platform is xbox
    return bRunningOnXbox;
}

我同意 Chuck 的评论,这可能不是 AnalyticsInfo 的目的...但与此同时,我们正在谈论 xbox - 一个由单一制造商负责的设备OS。所以至少在我看来,这似乎很安全。另外,如果你像这样包装它,如果出现更好的情况,换成不同的支票会非常容易。