Device information in Windows 8 store apps

Our Sticker Tales game tracks var­i­ous activ­i­ties via Google Ana­lyt­ics using code that grew into our CSharp­An­a­lyt­ics open source project.

But we also want to add some sys­tem met­rics that could help us answer other questions:

When is it time to exploit fea­tures of an OS update?
Do peo­ple on tablets play longer than peo­ple on laptops?
How long do var­i­ous timed activ­i­ties take by CPU?
Does not hav­ing a phys­i­cal key­board affect pur­chase flow completion?
To do this we want to record:

Proces­sor architecture
Device man­u­fac­turer, model and form fac­tor (category)
Win­dows ver­sion number
On Win­dows Phone and .NET this infor­ma­tion is eas­ily avail­able but in Win­dows Store apps it is not. Microsoft have made this dif­fi­cult because your appli­ca­tion should not change it’s behav­ior based on this infor­ma­tion.

The fol­low­ing code uses the PnPOb­ject API to best-guess these things. It is not bullet-proof and could eas­ily fail on machines with cus­tom HAL dri­vers (I haven’t seen one of those in years) or on other lan­guage edi­tions of Win­dows (not yet tried).

It is good enough in my opin­ion for ana­lyt­ics, log­ging or trou­bleshoot­ing and for noth­ing more.

To use it simply:

var windowsVersion = await SystemInfoEstimate.GetWindowsVersionAsync();
var processor = await SystemInfoEstimate.GetProcessorArchitectureAsync();

using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.Devices.Enumeration.Pnp;
using Windows.System;

public class SystemInfoEstimate
{
const string ItemNameKey = "System.ItemNameDisplay";
const string ModelNameKey = "System.Devices.ModelName";
const string ManufacturerKey = "System.Devices.Manufacturer";
const string DeviceClassKey = "{A45C254E-DF1C-4EFD-8020-67D146A850E0},10";
const string PrimaryCategoryKey = "{78C34FC8-104A-4ACA-9EA4-524D52996E57},97";
const string DeviceDriverVersionKey = "{A8B865DD-2E3D-4094-AD97-E593A70C75D6},3";
const string RootContainer = "{00000000-0000-0000-FFFF-FFFFFFFFFFFF}";
const string RootQuery = "System.Devices.ContainerId:=\"" + RootContainer + "\"";
const string HalDeviceClass = "4d36e966-e325-11ce-bfc1-08002be10318";

public static async Task<ProcessorArchitecture> GetProcessorArchitectureAsync()
{
var halDevice = await GetHalDevice(ItemNameKey);
if (halDevice != null && halDevice.Properties[ItemNameKey] != null) {
var halName = halDevice.Properties[ItemNameKey].ToString();
if (halName.Contains("x64")) return ProcessorArchitecture.X64;
if (halName.Contains("ARM")) return ProcessorArchitecture.Arm;
return ProcessorArchitecture.X86;
}
return ProcessorArchitecture.Unknown;
}

public static Task<string> GetDeviceManufacturerAsync()
{
return GetRootDeviceInfoAsync(ManufacturerKey);
}

public static Task<string> GetDeviceModelAsync()
{
return GetRootDeviceInfoAsync(ModelNameKey);
}

public static Task<string> GetDeviceCategoryAsync()
{
return GetRootDeviceInfoAsync(PrimaryCategoryKey);
}

public static async Task<string> GetWindowsVersionAsync()
{
// There is no good place to get this.
// The HAL driver version number should work unless you're using a custom HAL...
var hal = await GetHalDevice(DeviceDriverVersionKey);
if (hal == null || !hal.Properties.ContainsKey(DeviceDriverVersionKey))
return null;

var versionParts = hal.Properties[DeviceDriverVersionKey].ToString().Split('.');
return string.Join(".", versionParts.Take(2).ToArray());
}

private static async Task<string> GetRootDeviceInfoAsync(string propertyKey)
{
var pnp = await PnpObject.CreateFromIdAsync(PnpObjectType.DeviceContainer,
RootContainer, new[] { propertyKey });
return (string)pnp.Properties[propertyKey];
}

private static async Task<PnpObject> GetHalDevice(params string[] properties)
{
var actualProperties = properties.Concat(new[] { DeviceClassKey });
var rootDevices = await PnpObject.FindAllAsync(PnpObjectType.Device,
actualProperties, RootQuery);

foreach (var rootDevice in rootDevices.Where(d => d.Properties != null && d.Properties.Any())) {
var lastProperty = rootDevice.Properties.Last();
if (lastProperty.Value != null)
if (lastProperty.Value.ToString().Equals(HalDeviceClass))
return rootDevice;
}
return null;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值