What device is my application running on?

Windows Mobile comes in two main variants, traditionally called Pocket PC and Smartphone. If your application must run on both platforms, it may be necessary to detect at runtime what type of device your application is running on. This blog entry will discuss techniques .NET Compact Framework developers can use to achieve this.

Detecting the Platform
The .NET Compact Framework does not have any built in support for determining the type of device the application is running on, so we need to develop a small class library to query this information ourself.

The first platform we can check for is the desktop PC. We may want to determine if a user is attempting to run our Compact Framework application on their laptop, Tablet PC or Ultra Mobile PC (UMPC) for example.

// Returns true if the application is running on a
// desktop version of the Windows operating system
public static bool IsDesktopWindows
{
  get { return Environment.OSVersion.Platform != PlatformID.WinCE; }
}

As you can see it is reasonably straight forward to determine if we are running on a desktop version of Microsoft Windows. We simply query for the platform id of the operating system via the Environment.OSVersion property and return true if it does not equal Windows CE.

By switching the conditional around we can also detect if we are running on a device that utilises a Windows CE based operating system. This is what the IsWindowsCE property does, as shown below.

  // Returns true if the application is running on a
  // device powered by some form of Windows CE based
  // operating system.
  public static bool IsWindowsCE
  {
    get { return Environment.OSVersion.Platform == PlatformID.WinCE; }
  }

As discussed in my blog entry “Is Windows Mobile 6 powered by Windows Embedded CE 6.0?“, Windows CE is an operating system that can be further customised to develop particular variants, such as Windows Mobile. Once we know that a device is a Windows CE powered device, we can query the OS for some additional information which will help us narrow down the type of device even further.

  // Returns true if the application is running on a
  // Windows Mobile Standard (i.e. Smartphone) device
  public static bool IsWindowsMobileStandard
  {
    get
    {
      return IsWindowsCE()
        && (NativeMethods.GetPlatformType() == "SmartPhone");
    }
  }
 
  // Returns true if the application is running on a
  // Windows Mobile Professional (i.e. Pocket PC Phone
  // Edition) device. Also returns true for Windows
  // Mobile Classic devices (no cellular radio).
  public static bool IsWindowsMobileProfessional
  {
    get
    {
      return IsWindowsCE()
        && (NativeMethods.GetPlatformType() == "PocketPC");
    }
  }

The NativeMethods.GetPlatformType() method used in the last two properties is one which we will have to develop ourself. It utilises a Platform Invoke (PInvoke) call to access the SystemParametersInfo operating system API. By querying the SPI_GETPLATFORMTYPE system parameter we can get a string back which enables us to differentiate between the Pocket PC or Smartphone platforms. Since the implementation of NativeMethods.GetPlatformType() is rather long I have not included the source code here, please see the sample project available for download for its implementation.

Notice that as it stands our IsWindowsMobileProfessional property also returns a false positive, since it will return true if the device is a Windows Mobile Classic device (i.e. a Pocket PC without a cellphone). We will correct this issue in a couple of moments.

Detecting the Emulator
By querying yet another system parameter (SPI_GETOEMINFO) we can determine if our application is running on a physical device, or within a Device Emulator running on a desktop PC.

This can be a useful thing to tell. For example, you could disable device specific code (such as barcode scanner interfacing logic) while running within the emulator.

  public static bool IsEmulator()
  {
    return (NativeMethods.GetOEMInfo() == "Microsoft DeviceEmulator");
  }

Detecting device specific features
If possible you should detect specific device features (such as cellular radio presence, screen size or orientation) instead of detecting platform types. This will make your application more robust, since over time it is possible that some of the differentiating features between the platforms will disappear.

To differentiate between Windows Mobile Professional (with cellphone) and Windows Mobile Classic (without cellphone) devices, we will have to detect the presence of a cellular radio.

For some device features there are no nice APIs available to detect their presence. In this case you need to probe the device to determine if DLLs or registry keys specific to that device capability are present on a given device.

Prior to Windows Mobile 5.0 the recommended method to determine if a device had a built in cellular radio was to detect if a DLL called phone.dll was present within the device. This could be achieved as follows:

using System.IO;
 
public static bool HasPhone()
{
  return File.Exists(@"\Windows\Phone.dll");
}

With this additional method we can now alter our implementation of the IsWindowsMobileProfessional property to check that a cellular radio is present. Likewise we can create a new IsWindowsMobileClassic property which returns true only if HasPhone() returns false.

As the Windows Mobile platform grows, and new versions are released, the number of device features with standardised detection mechanisms typically improves. With Windows Mobile 5.0 or above, the OS provides us with a nice managed API we can call to determine if a cellular radio is present, as can be seen in this alternative implementation of the HasRadio() method.

using Microsoft.WindowsMobile.Status;
 
public static bool HasPhone()
{
  return SystemState.PhoneRadioPresent;
}

There are a number of other properties available within the SystemState class which can be used to detect other device features, such as a camera. If developing for Windows Mobile 5.0 or above it is defiantly worth looking into this class.

Detecting Platform Versions
Sometimes detecting that you are running on a Windows Mobile Professional device is not enough. You may desire to display a warning prompt for example, if you application is running on an operating system version newer than the one you officially support.

To do this you must use the properties we have developed above (IsWindowsMobileProfessional, IsWindowsMobileClassic etc) to determine the platform your application is running on and then compare the current operating system version number, obtained via the Envrionment.OSVersion property, against a list of known Windows CE versions for that platform.

For example with the Windows Mobile releases we know that the following Windows CE operating systems were utilised:

Platform Release Windows CE kernel version
Windows Mobile 6 5.2
Wndows Mobile 5.0 5.1
Windows Mobile 2003 SE 4.21

So we could determine if an application was running on a Windows Mobile 5.0 Pocket PC by implementing the following check:

  if (IsWindowsMobileProfessonal 
    && Environment.OSVersion.Version.Major == 5
    && Envrionment.OSVersion.Version.Minor == 1)
  {
    MessageBox.Show("This is a Windows Mobile 5.0 Pocket PC");
  }

In the future
As discussed by Daniel Moth the next version of the .NET Compact Framework (v3.5) will have a new property within the SystemSettings class called WinCEPlatform. This property contains one of the following enumerated values:

  • WinCEGeneric
  • PocketPC
  • Smartphone

This will allow you to detect the platform your application is running on quite easily, without needing to write custom code as we have needed to do.

Example

I have put together a
small demonstration application which demonstrates how to detect the various platforms your .NET Compact Framework application may run on.

If you load the application up within Visual Studio 2005 you should be able to switch between the various platforms via the “Change Target Platform…” option within the “Project” menu. When you then launch the application within different emulators you should be able to see the code detecting which platform the application is currently running on.

If you have a need for detecting the type of platform your application is running on feel free to use a copy the “Platform.cs” file within your own projects.

7 Responses to “What device is my application running on?”

  1. Jim Wilson has released a nice video tutorial today on how to implement this kind of platform/feature detection over on MSDN on the “How Do I: Detect and Identify a Mobile Device” page.

  2. John Wood says:

    This was very useful. Thanks.

    I was struggling a bit converting the C# to VB, until I found
    http://labs.developerfusion.co.uk/convert/csharp-to-vb.aspx
    Copied your module in, pasted the conversion to my project, worked straight off. Marvellous!

  3. Thanks John,

    I’m glad you have found the blog posting useful.

    My background is in C style languages (i.e. C, C++, Java, C# etc), hence why my .NET Compact Framework blog posts are all typically written in C#.

    I’m attempting to make my blog a useful resource for other developers, so I do wonder how much interest there would be in having VB.NET code samples along side the C# ones.

    Would it be enough to have two sample projects downloadable, one written in C#, the other in VB.NET? Or would the actual code snippets within the blog posts need to also be converted to VB.NET?

    When I respond to newsgroup questions etc in VB.NET I typically use the online translation tool you discovered to help me out.

  4. Nick says:

    Hi,
    Your blog is good for me,
    but how can i detect device is running on Window Mobile 6.1 or 6.0 ?

  5. Hi Nick,

    Please take a look at a more recent blog post of mine titled “How to detect Windows Mobile 6.1 (Detecting AKUs)“.

  6. tungtrungvn says:

    Thanks so much !

    Your code very useful

  7. Jane says:

    Thanks for the knowledge.
    I developed windows application on smartphone emulator but also need to work on classic and professional with Soft Input Panel being enabled on the proper devices. This did me great favour.

    Thanks
    Jane

Leave a Reply