Detect Universal App at Runtime in PCL

旧时模样 提交于 2020-01-06 16:53:13

问题


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

Thanks


回答1:


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?




回答2:


You have several ways: first:

  1. add PCL to main project (reference)
  2. create enum in PCL for determine type of OS (for ex. OperationSystemType)
  3. In main point (start) - for UWP it is App.cs pass right value to PCL

second (more flexible):

  1. Crete interface IApplicationProvider in any PCL
  2. Create implementation for each platform (in main project). You can add OSType property in interface (for ex.)
  3. Bind interface to implementation by IoC container in main project (App.cs)
  4. Get by IoC instance for interface and get right value



回答3:


One way to detect a platform from within a PCL is to try and load a type at runtime that is only available for that platform.

For example, for UWP, you could try to load type Windows.System.Profile.AnalyticsInfo, which is only available in a Windows 10 UWP application:

var win10Type = Type.GetType("Windows.System.Profile.AnalyticsInfo, Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime");

var isWin10UWP = win10Type != null;

It's not pretty, but it does work and the technique can be used to detect other platforms as well.



来源:https://stackoverflow.com/questions/36057853/detect-universal-app-at-runtime-in-pcl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!