Our Sticker Tales game tracks various activities via Google Analytics using code that grew into our CSharpAnalytics open source project.
But we also want to add some system metrics that could help us answer other questions:
When is it time to exploit features of an OS update?
Do people on tablets play longer than people on laptops?
How long do various timed activities take by CPU?
Does not having a physical keyboard affect purchase flow completion?
To do this we want to record:
Processor architecture
Device manufacturer, model and form factor (category)
Windows version number
On Windows Phone and .NET this information is easily available but in Windows Store apps it is not. Microsoft have made this difficult because your application should not change it’s behavior based on this information.
The following code uses the PnPObject API to best-guess these things. It is not bullet-proof and could easily fail on machines with custom HAL drivers (I haven’t seen one of those in years) or on other language editions of Windows (not yet tried).
It is good enough in my opinion for analytics, logging or troubleshooting and for nothing 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;
}
}
分享到:
相关推荐
- **Concept**: The Keychain is a secure storage mechanism that allows developers to store sensitive information, such as passwords and tokens, securely on the device. - **Implementation**: ...
Material ID for Android Material ID is a simple app to get some device information (version, bootloader, ID, CPU, etc) and test device features. Design inspired by Material Design. Google Play ...
Monitor your hardware in real time and get complete information about your device model, CPU, GPU, memory, battery, camera, storage, network, sensors and operating system. DevCheck shows all the ...
with Glances to provide timely information, notifications to inform your users of the latest updates, and watch face complications to show your users data as soon as they raise their wrists, your ...
This is the first guide to focus on one of the most critical aspects of Android development: how to efficiently store, retrieve, manage, and share information from your app’s internal database....
The app is released on Google Play: https://play.google.com/store/apps/details?id=org.anothermonitor. IMPORTANT NOTICE for Android 7.0 users Due to undocumented changes made by Google, on Android 7.0 ...
Download Boardwalk from Google Play: https://play.google.com/store/apps/details?id=net.zhuoweizhang.boardwalk Download APK for latest beta of Boardwalk: ...
versionInfo - Used to repopulate the version information in AndroidManifest.xml since newer aapt requires version information to be passed via parameter compressionType - Used to determine the ...
Based on the provided information from "iOS 5 Programming Cookbook" by Vandad Nahavandipoor, we can derive a comprehensive set of knowledge points related to iOS development using Objective-C....
Store Custom Functions in the Crystal Repository and reuse them across multiple reports. Custom Templates ?Spend less time formatting individual reports. With standardized formatting and logic, ...