Search code examples
.netc#-4.0win-universal-appportable-class-librarywindows-10-universal

Detect Universal App at Runtime in PCL


Is there any way to detect that a main application is a Universal App (W10) from a Portable Class Library?

Thanks


Solution

  • Out-of-the-box I do not think the functionality you are asking for is available in PCL, but here is a suggestion involving reflection that you might want to try.

    It is adapted to the PCL Profile (328) you are using, involving .NET 4 and Silverlight 5. The GetPlatformName method needs to be somewhat adjusted if you want to for example switch to PCL profiles 111 and 259, since these profiles would have to rely on TypeInfo rather than Type.

    Here is the proposed method and accompanying interface, which can be implemented in the Portable Class Library:

    public static class RuntimeEnvironment
    {
        public static string GetPlatformName()
        {
            var callingAssembly = (Assembly)typeof(Assembly).GetMethod("GetCallingAssembly").Invoke(null, new object[0]);
            var type = callingAssembly.GetTypes().Single(t => typeof(IPlatform).IsAssignableFrom(t));
            var instance = (IPlatform)Activator.CreateInstance(type);
            return instance.PlatformName;
        }
    }
    
    public interface IPlatform
    {
        string PlatformName { get; }
    }
    

    Apart from the above code, you will also need to implement the IPlatform interface in each platform-specific application, for example like this:

    public class UniversalPlatform : IPlatform
    {
        public string PlatformName => "UWP";
    }
    

    In short, the GetPlatformName method instantiates the single class implementing the IPlatform interface in the calling (application) assembly, and returns the PlatformName property.

    The Assembly.GetCallingAssembly method is not publicly exposed in any of the PCL profiles, but it is generally implemented and can therefore be accessed via reflection.

    The GetPlatformName method is fully portable and can thus be consumed within the Portable Class Library itself, allowing you to make platform conditional decisions within the PCL code. The proposal does require minimal code efforts within each platform-specific application, since you do need to implement IPlatform, but maybe that is an acceptable price to pay?