Skip to main content

Accessing hardware configuration from a Metro App

When we create Metro Apps for Windows 8, we could imagine some scenario where we would like include some device resources information like CPU or memory usage.
The bad news is that we cannot get this data from the device. And yes, Windows 8 works as expected. We need to realize that a Metro App run on Windows 8 in a very isolated environment. The application don’t need to know one what environment run, how many memory is used by the system and so on. The lifetime of the Metro App is controlled by the operating system and all the resources that an application can need are offered by the system.
Remember? A Metro App should do only one think, but it should do this think best. In this moment I cannot imagine extreme Metro Apps, like some other desktop application that can do almost anything. If we realize that we work at a Metro App that do to many thinks, that a good idea is to split it in 3,4 or why not 10 applications. When we have a user that accesses our application, we don’t want to have a user that is lost in 97 functionalities. In the moment when he opens the Metro App we want to let him to do only one thinks, without any problems. I have nightmares with desktop applications that were so complicated that I could not remember how I can submit my time report or what I can send a message to admin.
Even if we cannot obtain real time information, we can query the operating system about what kind of processor have, what other devices are connected to our device or what printers are installed.
Let’s see what information can we access and how. The PerformanceCounter don’t exist anymore in Metro Apps. It can be found only in desktop applications. We still have functions named GetNativeSystemInfo that can be used only for applications that run on x64. But you will not be able to extract a lot of information from there. Don’t expect to be able to retrieve the processor load or memory level.
What I tried to use to get information about the device was DeviceInformation.FindAllAsync(…). This is the official way that can be used to get device information. The first parameters that need to be specified are the interface GUID. Based on this GUID specific information will be loaded. Some GUID values that can be used are:
  • {0ECEF634-6EF0-472A-8085-5AD023ECBCCD} – Printer interface
  • {6AC27878-A6FA-4155-BA85-F98F491D4F33} – External devices connected (portable devices)
  • {E5323777-F976-4F5B-9B55-B94699C46E44} – Webcam interface
In general the second parameter will remain NULL, but it can be useful when we want to filter the result based on object property.
var printers = await DeviceInformation.FindAllAsync(
“{0ECEF634-6EF0-472A-8085-5AD023ECBCCD}”,
null);
In this C# example we got the list of printers installed on the device. The Java Script equivalent for this command is:
Windows.Devices.Enumeration.DeviceInformation.findAllAsync(
‘"System.Devices.InterfaceClassGuid:="{97FADB10-4E33-40AE-359C-8BEF029DBDD0}""’,
null)
.done(function(printers) {
// iterate through items.
}
For Java Script is mandatory to add the also the given text before the GUID (don’t’ forget about the “”). When now results are found the count of the returned collection is 0 and not NULL.
Now, let see a small hack with this function. Normally we can access only printers, webcam and external devices. But this method was port from Windows 7, where we can access other information also. If we know the correct GUID and are not limited by Windows 8 we can access other data also. For example if we set the GUID to “{0ECEF634-6EF0-472A-8085-5AD023ECBCCD}” we will get the list of processor on that computer. For example for my PC I got a list with the following content:
Intel(R) Core(TM) i7 CPU       2630QM @ 2.00GHz
I thinks that also other information can be accessed based on the GUID. Did you found other GUID that are working?

Comments

  1. The programmer thinks, the application does things.. ;)

    Anyway, it's expected that a Metro app can't get to much hardware info - first it runs in a sandbox, second, the OS abstracts away the hardware layer (Intel platform, Arm etc..), like any Silverlight or JavaScript application now.

    ReplyDelete
    Replies
    1. There could be people that imagine apps that display the resource status of the device.
      And is not so abstract. We still need to create 3 types of packages, one for x84, x64 and ARM.

      Delete
    2. Suge, general info it's possible to get, but probably the king of utilities like SySoftware Sandra won't be possible to implement using a normal Metro app..

      In general the source code for Metro apps is supposed to be portable across architecture (even if it's necessary to compile or package it separately for each platform).

      It's nothing new - similar sandboxes exists for a long time in Java applets or Silverlight, with more or less restrictions.

      Delete

Post a Comment

Popular posts from this blog

Windows Docker Containers can make WIN32 API calls, use COM and ASP.NET WebForms

After the last post , I received two interesting questions related to Docker and Windows. People were interested if we do Win32 API calls from a Docker container and if there is support for COM. WIN32 Support To test calls to WIN32 API, let’s try to populate SYSTEM_INFO class. [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; } ... [DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI); ... SYSTEM_INFO pSI = new SYSTEM_INFO(

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine: threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration: TeamCity .NET 4.51 EF 6.0.2 VS2013 It see

Navigating Cloud Strategy after Azure Central US Region Outage

 Looking back, July 19, 2024, was challenging for customers using Microsoft Azure or Windows machines. Two major outages affected customers using CrowdStrike Falcon or Microsoft Azure computation resources in the Central US. These two outages affected many people and put many businesses on pause for a few hours or even days. The overlap of these two issues was a nightmare for travellers. In addition to blue screens in the airport terminals, they could not get additional information from the airport website, airline personnel, or the support line because they were affected by the outage in the Central US region or the CrowdStrike outage.   But what happened in reality? A faulty CrowdStrike update affected Windows computers globally, from airports and healthcare to small businesses, affecting over 8.5m computers. Even if the Falson Sensor software defect was identified and a fix deployed shortly after, the recovery took longer. In parallel with CrowdStrike, Microsoft provided a too