在 PCL 内在运行时检测通用应用程序

Detect Universal App at Runtime in PCL

有什么方法可以检测到主应用程序是来自便携式 Class 库的通用应用程序 (W10)?

谢谢

你有几种方法: 第一:

  1. 将PCL添加到主项目(参考)
  2. 在 PCL 中创建 enum 以确定 OS 的类型(例如 OperationSystemType
  3. 要点(开始)- 对于 UWP,它是 App.cs 将正确的值传递给 PCL

第二(更灵活):

  1. 任何 PCL
  2. 中的克里特岛界面 IApplicationProvider
  3. 为每个平台创建实现(在主项目中)。您可以在界面中添加OSType 属性(例如)
  4. 在主项目中通过 IoC 容器实现绑定接口 (App.cs)
  5. 通过接口的IoC实例获取并获取正确的值

开箱即用 我认为 PCL 中没有您要求的功能,但这里有一个涉及反射的建议,您可能想尝试一下。

它适用于您正在使用的 PCL 配置文件 (328),涉及 .NET 4 和 Silverlight 5。如果您想切换 GetPlatformName 方法,则需要进行一些调整PCL 配置文件 111 和 259,因为这些配置文件必须依赖 TypeInfo 而不是 Type.

这是建议的方法和附带的接口,可以在便携式 Class 库中实现:

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; }
}

除上述代码外,您还需要在每个特定于平台的应用程序中实现 IPlatform 接口,例如:

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

简而言之,GetPlatformName 方法在调用(应用程序)程序集中实例化实现 IPlatform 接口的单个​​ class,returns PlatformName 属性.

Assembly.GetCallingAssembly 方法未在任何 PCL 配置文件中公开公开,但通常已实现,因此可以通过反射访问。

GetPlatformName 方法是完全可移植的,因此可以在可移植 Class 库本身中使用,允许您在 PCL 代码中做出平台条件决策。该提案确实需要在每个特定于平台的应用程序中进行最少的代码工作,因为您确实需要实施 IPlatform,但也许这是可以接受的代价?

从 PCL 中检测平台的一种方法是尝试在运行时加载仅适用于该平台的类型。

例如,对于 UWP,您可以尝试加载类型 Windows.System.Profile.AnalyticsInfo,它仅在 Windows 10 UWP 应用程序中可用:

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

var isWin10UWP = win10Type != null;

它不是很漂亮,但确实有效,而且该技术也可用于检测其他平台。