根据WPF中的运行时操作系统版本有条件地使用引用的程序集

时间:2019-02-10 20:48:00

标签: .net wpf unity-container .net-assembly assemblybinding

我正在尝试将Windows 10 Notifications / Action中心集成到现有的WPF应用程序(.NET Framework 4.7.2)中,该应用程序需要向下运行到Windows7。该应用程序是通过WiX MSI安装的。

该应用程序使用Prism + Unity进行依赖项注入。

解决方案(出于问题的目的而简化了)有三个项目:

App.WPF-WPF应用程序的入口点,是视图/控件的宿主

App.WPF.Win10-包含Win10通知的必要参考和代码

App.WPF.Core-包含视图模型,并通过Unity注入依赖项

App.WPF引用了App.WPF.Win10App.WPF.Core

App.WPF.Win10仅引用App.WPF.Core,并且包含桌面敬酒通知示例中提供的found on github中的DesktopNotificationManagerCompat。由于此程序集使用Win10 UWP API,因此它引用了Win10 sdk,以及仅用于Win10通知的其他两个程序集。

在容器注册中,将Windows 10 NotificationManager实现(App.WPF.Win10)或App.WPF.Core抽象(INotificationManager)的虚拟对象(App.WPF.Core)注册到容器,基于运行时操作系统版本。这使使用通知的代码不必担心检查它们是否可以安全地尝试和使用通知。

注册代码如下:

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    ....

    if (WindowsRelease >= WindowsRelease.TH1)
    {
       NotificationActivator.Application = this;
       containerRegistry.RegisterSingleton<INotificationManager, Win10.NotificationManager>();
    }
    else
    {
        containerRegistry.RegisterSingleton<INotificationManager, Core.NotificationManager>();
    }

    ...
}

Win10.NotificationManagerNotificationActivatorApp.WPF.Win10项目提供,由App.WPF引用,Core.NotificationManagerApp.WPF.Core提供。 / p>

如果我将WiX设置为在Windows 7上安装所有引用的dll(甚至包括Win10特定的dll),那么一切似乎都可以正常工作,正确的NotificationManager已注册,并且一切正常。我真的不想在不需要的计算机上部署Win10特定的二进制文件,如果可以避免的话。

然后我将WiX配置为根据安装计算机的OS版本有条件地部署App.WPF.Win10组件(和必要的依赖项)。安装程序正在部署正确的有效负载,但在Windows 7(未部署二进制文件)上,由于运行时尝试在以下位置加载FileNotFoundException程序集而导致的容器注册期间App.WPF.Win10导致应用启动失败RegisterTypes的调用点,因为运行时可以查看正在使用的程序集中的类型潜在

是否可以编写RegisterTypes方法或配置解决方案/项目,以使运行时除非真正需要,否则不会尝试加载App.WPF.Win10程序集,即运行时操作系统为Windows 10 TH1 +。

我还希望避免针对Win 10和其他操作系统生成多个版本和MSI。

0 个答案:

没有答案