应用开发中,开发者时常需要获取一些系统、用户信息用于数据统计遥测、问题反馈、用户识别等功能。本文旨在介绍在 Windows UWP 应用中获取一些常用系统、用户信息的方法。示例项目代码可参见 Github:

https://github.com/validvoid/UWP-SystemInfoCollector

由于涉及内容较多,故本文会分为多篇展开。本篇介绍获取设备和系统的基本信息、应用包信息、用户数据账户信息和用户账户信息。

原博客阅读地址:http://validvoid.net/uwp-system-info-collect-1/

AnalyticsInfo

Windows.System.Profile 命名空间下的 AnalyticsInfo 类负责提供用于设备分析的相关信息。通过此类,我们能够获得系统的具体版本号以及设备类型等信息。

通过 AnalyticsInfo 类中的 VersionInfo 属性我们可以获取当前应用运行设备的设备类型和操作系统具体版本。AnalyticsVersionInfo 类型的 VersionInfo 属性包含两个成员:

DeviceFamily属性的返回值类型为字符串。其提供的设备类型信息极为重要,几乎在所有 UWP 开发中均会用到。通常我们都会根据此属性返回的设备类型信息配合实现应用的响应式设计。例如,返回 "Windows.Desktop" 时表示应用运行在桌面端 Windows 10 上,则应用呈现适合于鼠标键盘操作的 PC 端界面;返回 "Windows.Mobile" 时表示应用运行在移动端的 Windows 10 上,则应用应当呈现适合于触屏操作的移动端小屏界面。

DeviceFamilyVersion 属性的返回值类型也是字符串。其返回值指示了当前设备运行的 Windows 的具体版本号。不过直接获取此属性拿到的返回值是一个形如 "2814750460870692" 的 long 型数字。如果想要获取可读的 "major.minor.revision.build" 形式的版本号,需要先将此数值转化为十六进制,然后进一步转化为可读的版本号。

格式化版本号的 C# 代码:

string sv = AnalyticsInfo.VersionInfo.DeviceFamilyVersion;
ulong v = ulong.Parse(sv);
ulong v1 = (v & 0xFFFF000000000000L) >> ;
ulong v2 = (v & 0x0000FFFF00000000L) >> ;
ulong v3 = (v & 0x00000000FFFF0000L) >> ;
ulong v4 = (v & 0x000000000000FFFFL);
string version = $"{v1}.{v2}.{v3}.{v4}";

运行示例代码会得以类似以下内容的输出:

Device Analytics Info

DeviceForm: Unknown
DeviceFamily: Windows.Desktop
DeviceFamilyVersion: 2814750460870692
Reconstructed OS Version: 10.0.10586.36

需要指出的是,如果你打算通过 DeviceFamilyVersion 进行数据统计、分析工作,那么在应用的客户端代码中不要将原始的 DeviceFamilyVersion 返回值格式化为可读形式。据微软官方人员在 MSDN 的解释,AnalyticsInfo.VersionInfo 旨在为遥测和日志记录提供一个不透明的版本号字符串值,最佳做法是将该原始值传回服务器,如果有必要,在服务器端进行格式化解析的工作。

另外,AnalyticsInfo 类中的 DeviceForm 属性具体作用不明,在 PC 和 Windows Mobile 设备中均返回 "Unknown"。MSDN 文档中仅将此属性描述为 "Gets the device form."

资源限定符

Windows.ApplicationModel.Resources.Core.ResourceContext 类封装了可能影响资源选定的资源限定符(qualifiers)。这些资源限定符影响了应用运行时所需资源的选定。查询资源限定符并做出适当匹配优化对于增进用户体验也有帮助。

要获得当前应用的资源限定符,我们需要调用 ResourceContext.GetForCurrentView() 方法获得当前应用视图的资源上下文,再访问其中的 QualifierValues 属性。QualifierValues 属性的类型为 IObservableMap<string,string>,可通过键名获得对应的限定符值。

以下为 MSDN 文档中列举的可能的资源限定符名称以及对应取值:

资源限定符 可能的取值 说明
Language 如 "en-us" 此限定符名称可以映射到表示语言的字符串值,例如,"en-us" 表示美国英语。
Contrast standard 此限定符名称可以映射到当前对比度设置值。
high
black
white
Scale 80 此限定符名称可以映射到以百分比形式表示显示比例的值。
100
120
140
150
160
180
225
HomeRegion 如 "021" 此限定符名称可以映射到表示区域的字符串值,例如,"021" 表示北美。
TargetSize 如 "256" 此限定符名称可以映射到表示目标大小的字符串值,例如,"256"。
LayoutDirection LTR 此限定符名称可以映射到当前布局方向的值。
RTL
TTBLTR
TTBRTL
Configuration   此限定符名称可以映射到表示配置的字符串值。
AlternateForm   此限定符名称可以映射到表示替换窗体的字符串值。
DXFeatureLevel DX9 此限定符名称可以映射到表示 DirectX 功能级别。
DX10
DX11

有关 ResourceContext 类的更多用法,可以参阅 MSDN 文档 ResourceContext 类型

获取当前应用包信息

Windows.ApplicationModel.Package 类型负责提供应用包的信息。要获取当前应用的 Package 对象实例,可以通过 'Package.Current' 属性获取。获取当前应用的包对象之后,我们就可以进一步获得以下信息:

  • DisplayName 获取包的显示名称。
  • InstalledDate 获取包安装或最近一次更新的时间。
  • InstalledLocation 获取包的安装位置。返回值为 StorageFolder 类型。
  • IsBundle 指示该包是否为 Bundle 集合包。
  • IsDevelopmentMode 指示该包是否以开发模式安装。
  • IsFramework 指示是否有其它包将该包声明为依赖项。
  • IsResourcePackage 指示该包是否为资源包。
  • Logo 获取该包 Logo 文件的位置。返回值为 Uri 类型。
  • PublisherDisplayName 获取包发布者显示名称。
  • InstallDate 获取应用包初次安装的时间。该属性在 Windows 10 上并未实现。过去也仅对 Windows Phone 8 有效。

除以上属性外,Package 类还提供了三个重要的属性:Id 、 Status 以及Dependencies

Id 属性为 PackageId 类型。该属性提供了当前包 Id 的各种信息,包括:

  • Architecture 获取当前包的对应处理器架构。
  • FamilyName 获取包的 Family Name。如 "32b04fa8-6b7b-4ed9-8a9b-eade01a24207_hpzxbeh1zj56g "
  • FullName 获取包的完整名称。如 "32b04fa8-6b7b-4ed9-8a9b-eade01a242071.0.0.0x86__hpzxbeh1zj56g"
  • Name 获取包名。如 "32b04fa8-6b7b-4ed9-8a9b-eade01a24207"
  • Publisher 获取包发布者。如 "CN=validvoid"
  • PublisherId 获取包发布者 ID。
  • ResourceId 获取包的资源 ID。
  • Version 获取包版本。返回值为 PackageVersion 类型,可进一步格式化输出字符串。
  • Author 获取包作者。仅限 Windows Phone,在 Windows 10 上无效。
  • ProductId 获取包的 ProductID 属性值。仅限 Windows Phone,在 Windows 10 上无效。

Status 属性为 PackageStatus 类型。该类型提供了一个 VerifyisOK() 方法用于判断当前包的状态是否良好,可以使用。该方法会验证 PackageStatus 中的一系列属性以判断包是否可用。PackageStatus 包含的属性如下:

  • DataOffline 指示当前包所用数据是否离线。例如,当应用的数据安装在了 SD 卡等可移动介质上,而该媒体弹出时,数据即为离线状态,则该属性返回 true。
  • DependencyIssue 指示包的依赖项状态。当当前包的依赖项之一遭遇异常时,该属性即返回 true。在当前包的全部依赖项解决问题前,当前包将无法使用。
  • DeploymentInProgress 指示当前包是否正在被部署过程占用。例如,当包正在更新时,该属性返回 true。
  • Disabled 指示当前包是否被禁用。包可以通过PackageManager.SetPackageStatus 进行禁用,或通过PackageManager.ClearPackageStatus 启用。
  • LicenseIssue 指示当前包是否有授权问题。例如当授权丢失或过期时,该属性返回 true。所有授权问题解决前,当前包将不可用。
  • Modified 指示当前包是否存在内容修改问题。例如,当包丢失了某些文件时,该属性返回 true。
  • NeedsRemediation 指示当前包是否需要进行修正。例如,当 NotAvailableLicenseIssueModifiedTampered 中的一个或多个属性指示出当前包存在异常情况时,该属性即为 true。
  • NotAvailable 指示当前包是否不可用。例如,当 DataOfflineDisabledPackageOffline 中的一个或多个属性指示出当前包存在异常情况时,该属性即为 true。
  • PackageOffline 指示当前包是否离线或不能访问。例如,当包文件安装在 SD 卡等可移动介质上,且该介质处于被移除,则该属性为 true。
  • Servicing 指示当前包是否处于被占用状态。
  • Tampered 指示当前包是否处于感染状态。改属性返回 true 的一种可能原因是第三方反病毒软件将当前包标记为了恶意程序。

Dependencies 属性为 IReadOnlyList<Package> 类型,可用于获取当前包的所有依赖项。注意该属性仅用于获取 Windows Store 应用包的依赖项。要获取一个桌面应用包的依赖项,需使用 Win32 函数 GetPackageInfo

有关 Package 的具体用法可参见 Github 上的示例代码。

列举 Windows Mobile 设备上已部署的应用包

Windows.Phone.Management.Deployment 命名空间下提供了一系列用于控制应用部署功能的类型,其中 InstallationManager 类型负责应用包的安装管理。我们可以通过其中的 FindPackagesForCurrentPublisher 方法获得当前 Windows Mobile 设备上安装的同一发布者的应用包部署情况。该方法的返回类型为 IEnumerable<Package>,我们可以进一步检索返回值获取具体某个应用包的详细信息甚至启动这些应用。

值得说明的是,Windows.Phone.Management.Deployment 仅在 Windows Mobile 设备上有效,故在 UWP 应用中使用时,需要配合 AnalyticsInfo.VersionInfo.DeviceFamily 检测当前设备类型,选择是否调用该命名空间下的方法。另外,'InstallationManager' 类中提供的其它方法需要 ID_CAP_OEM_DEPLOYMENT 特别权限才能够正常使用,故一般开发者无法使用。

获取用户数据账户信息

用户数据账户是什么呢?举例说明,如果你用过 Android 系统,那么你在 Android 的系统设置中会看到一项名为“账户”(Accounts)的设置栏目,其中列出了当前系统登录的 Gmail、Outlook、Office、Exchange、微博等各种应用注册的账户。这些账户就是用户数据账户。Windows.ApplicationModel.UserDataAccounts 命名空间定义了用于控制邮件、预约、日历等用户数据账户信息的相关类型和枚举。其中,UserDataAccount 类型表示一个用于存取邮件、联系人、日历等数据的用户数据账户。UserDataAccountManager类型提供了与用户数据账户交互的 API。UserDataAccountStore 代表用户数据账户的储存区。本文主要讲述如何通过 Windows Store App API 获取一些常用的信息,故在此不涉及操作用户数据账户的内容。仅关注如何获得一些数据。

要使用 UserDataAccounts 相关 API,要求应用在清单文件中声明联系人(contacts)、预约(appointments)、邮件(email)等功能中的一个或多个。

假设我们想要列举出当前系统上登录的所有用户数据账户,并输出这些账户的相关信息,首先我们需要通过 UserDataAccountManager.RequestStoreAsync 方法向系统请求用户数据账户的储存区。该方法接受一个 UserDataAccountStoreAccessType 枚举类型的参数。该参数用于指定要求的用户数据账户存储区的访问类型。UserDataAccountStoreAccessType枚举包含两个成员:

  • AllAccountsReadOnly 对应用以及系统的用户数据账户进行只读访问
  • AppAccountsReadWrite 对当前应用的用户数据储存区进行读/写访问

由枚举可知,我们虽然可以检索当前应用自身以外的用户数据账户,但对于自身以外的用户数据账户并没有写权限。

这里我们选择第一种访问类型,使用以下代码请求用户数据账户储存区:

UserDataAccountStore userDataAccountStore = await UserDataAccountManager.RequestStoreAsync(UserDataAccountStoreAccessType.AllAccountsReadOnly);  

获取到的用户数据账户储存区实例为 UserDataAccountStore 类型,该类型包含三个方法:

这里我们调用 FindAccountsAsync 即可获得所有用户数据账户,并进行下一步操作。具体演示可参见 Github 上的示例代码。

获取系统用户信息

在 Windows 8 应用中,我们使用 Windows.System.UserProfile 命名空间中的UserInformation 访问系统登录的用户账户信息。而在 Windows 10 以及以后版本的 Windows 中,UserInformation 不再被支持。因为在 Windows 10 中,除非用户授权,应用是不能获取用户信息的。而 Windows 8 应用则是默认得到授权的。并且,旧的 Windows 8 应用运行于 Windows 10 时也无法正常获取用户信息。

在 Windows 10 上我们需要使用新的 API 提供的Windows.System.User 类型获取用户信息。注意使用该 API 需要应用在清单文件中配置“用户账户信息”(User Account Information) 功能。

User 类提供了三个静态方法及其重载:

我们可以通过 FindAllAsync 或 GetFromId 方法获取用户账户实例,获取用户后,可以通过调用 GetPropertyAsync 方法取得该用户的属性信息。GetPropertyAsync 方法接受一个 string 类型的参数,具体传入内容可以通过 KnownUserProperties 类中定义的属性获取。 KnownUserProperties 类中定义了已知可用的用户账户属性键名。例如,我们想要获取账户显示名称时,可以采用如下方法:

string displayName = await user.GetPropertyAsync(KnownUserProperties.DisplayName);  

User 类还包含以下三个属性成员:

配合使用 UserDataAccount 和 User 两个 API 可以使应用更好地实现唯一用户识别、用户账户体系、自定义授权等功能特性。


更多内容请参阅本文后续内容更新。

第二篇:UWP 应用获取各类系统、用户信息 (2) - 商店授权信息、零售演示模式信息、广告 ID、EAS 设备信息、硬件识别信息、移动网络信息

阅读地址:http://validvoid.net/uwp-system-info-collect-2/

UWP 应用获取各类系统、用户信息 (1) - 设备和系统的基本信息、应用包信息、用户数据账户信息和用户账户信息的更多相关文章

  1. UWP 应用获取各类系统、用户信息 (2) - 商店授权信息、零售演示模式信息、广告 ID、EAS 设备信息、硬件识别信息、移动网络信息

    应用开发中,开发者时常需要获取一些系统.用户信息用于数据统计遥测.问题反馈.用户识别等功能.本文旨在介绍在 Windows UWP 应用中获取一些常用系统.用户信息的方法.示例项目代码可参见 Gith ...

  2. linux 下如何查看和踢除正在登陆的其它用户 ==>Linux下用于查看系统当前登录用户信息的4种方法

    在linux系统中用pkill命令踢出在线登录用户 由于linux服务器允许多用户登录,公司很多人知道密码,工作造成一定的障碍 所以需要有时踢出指定的用户 1/#who   查出当前有那些终端登录(用 ...

  3. 简单的股票信息查询系统 1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环) 2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来 3 允许按股票价格、涨跌幅、换手率这几列来筛选信息, 比如输入“价格>50”则把价格大于50的股票都打印,输入“市盈率<50“,则把市盈率小于50的股票都打印,不用判断等于。

    '''需求:1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环)2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来3 允许按股票价格 ...

  4. UNIX系统高级编程——第六章-系统数据文件和信息-总结

    口令文件: /* The passwd structure. */ struct passwd { char *pw_name; /* Username. */ char *pw_passwd; /* ...

  5. Golang模拟用户登陆,突破教务系统

    目录 一.Golang模拟用户登陆,突破教务系统 1.1 请求登陆页面 1.2 抓包分析登陆请求 1.3 golang使用js引擎合成salt 1.4 模拟表单提交,完成登陆 1.5 进入成绩查询页, ...

  6. Oracle sys和system用户、sysdba 和sysoper系统权限、sysdba和dba角色的区别

    sys和system用户区别 1)最重要的区别,存储的数据的重要性不同 sys所有oracle的数据字典的基表和视图都存放在sys用户中,这些基表和视图对于oracle的运行是至关重要的,由数据库自己 ...

  7. 百万用户时尚分享网站feed系统扩展实践

    Fashiolista是一个在线的时尚交流网站,用户可以在上面建立自己的档案,和他人分享自己的以及在浏览网页时看到的时尚物品.目前,Fashiolista的用户来自于全球100多个国家,用户达百万级, ...

  8. Linux学习总结(十二)—— CentOS用户管理:创建用户、修改用户、修改密码、密码有效期、禁用账户、解锁账户、删除用户、查看所有用户信息

    文章首发于Linux学习总结(十二)-- CentOS用户管理,请尊重原创保留原文链接. 创建用户 useradd -g webadmin -d /home/zhangsan zhangsan pas ...

  9. 【转】Oracle Sys和system用户、sysdba 和sysoper系统权

    一:最重要的区别,存储的数据的重要性不同 [sys]所有oracle的数据字典的基表和视图都存放在sys用户中,这些基表和视图对于oracle的运行是至关重要的,由数据库自己维护,任何用户都不能手动更 ...

随机推荐

  1. 洛谷P4526 【模板】自适应辛普森法2(Simpson法)

    题面 传送门 题解 据说这函数在\(x>15\)的时候趋近于\(0\) 据说当且仅当\(a<0\)时积分发散 所以直接套自适应\(simpson\)吧-- //minamoto #incl ...

  2. python自带的排列组合函数

    需求: 在你的面前有一个n阶的台阶,你一步只能上1级或者2级,请计算出你可以采用多少种不同的方法爬完这个楼梯?输入一个正整数表示这个台阶的级数,输出一个正整数表示有多少种方法爬完这个楼梯. 分析:提炼 ...

  3. 公司拷贝回家的工程用sts导入clean package报错java.lang.NoClassDefFoundError

    从公司拷贝工程回家加班,用相同版本的sts和jdk但是run as    maven build   clean package 总是报错java.lang.NoClassDefFoundError: ...

  4. 如何用python批量翻译文本?

    首先,看一下百度翻译的官方api文档. http://api.fanyi.baidu.com/api/trans/product/apidoc # coding=utf-8 #authority:bi ...

  5. postgreSQL PL/SQL编程学习笔记(四)

    Errors and Messages 1. Reporting Errors and Messages Use the RAISE statement to report messages and ...

  6. Python3之uuid模块

    一. 简介 UUID是128位的全局唯一标识符,通常由32字节的字母串表示.它可以保证时间和空间的唯一性,也称为GUID. 全称为:UUID--Universally Unique IDentifie ...

  7. Eclipse设置自动生成的javadoc

    1.点击 Window -> Preference -> Java -> Code Style -> Code Template ,在右边选择 Comments -> 相 ...

  8. SDUT OJ 数据结构实验之链表二:逆序建立链表

    数据结构实验之链表二:逆序建立链表 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...

  9. springboot整合mybatis,redis,代码(一)

    一 搭建项目,代码工程结构 使用idea或者sts构建springboot项目 二  数据库sql语句 SQLyog Ultimate v12.08 (64 bit) MySQL - 5.7.14-l ...

  10. Home Web Server 1.9.1 build 164 - CGI Remote Code Execution复现

    一.  Home Web Server 1.9.1 build 164 - CGI Remote Code Execution复现 漏洞描述: Home Web Server允许调用CGI程序来通过P ...