Использование ссылочных сборок, условно основанных на версии ОС времени выполнения в WPF - PullRequest
0 голосов
/ 10 февраля 2019

Я экспериментирую с интеграцией Центра уведомлений и действий Windows 10 в существующее приложение WPF (.NET Framework 4.7.2), которое должно работать на более низком уровне, чем Windows 7. Приложение устанавливается через MSI WiX.

Приложение использует Prism + Unity для внедрения зависимостей.

Решение (упрощенное для целей вопроса) имеет три проекта:

App.WPF - точка входа для WPFприложение и домашняя страница для просмотра / управления

App.WPF.Win10 - содержит необходимые ссылки и код для уведомлений Win10

App.WPF.Core - содержит модели представления с зависимостями, введенными через Unity

App.WPF ссылается на App.WPF.Win10 и App.WPF.Core.

App.WPF.Win10 ссылается только на App.WPF.Core и содержит DesktopNotificationManagerCompat, как указано в примере уведомления о тостах на рабочем столе, который можно найти наGitHub .Поскольку эта сборка использует API-интерфейсы Win10 UWP, в ней есть ссылки на 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.NotificationManager и NotificationActivatorпредоставляются проектом App.WPF.Win10, на который ссылается App.WPF, а Core.NotificationManager предоставляется App.WPF.Core.

Если я установлю WiX для установки всех ссылочных dll (даже определенных для Win10) наWindows 7, кажется, все работает нормально, правильные NotificationManager регистрируются и все работает нормально;Я действительно не хочу развертывать специфичные для Win10 двоичные файлы на компьютерах, где они не нужны, хотя, если этого можно избежать.

Затем я настроил WiX для развертывания компонента App.WPF.Win10 (и необходимых зависимостей), условно на основена установленной машине версия ОС.Установщик развертывает правильную полезную нагрузку, но в Windows 7 (где двоичные файлы не развернуты) запуск приложения завершается неудачно из-за FileNotFoundException во время регистрации контейнера, вызванного средой выполнения, пытающейся загрузить сборку App.WPF.Win10 в точке вызована RegisterTypes, поскольку среда выполнения может видеть типы из сборки , потенциально .

Можно ли написать метод RegisterTypes или настроить решение / проект в таком видеспособ, которым среда выполнения не будет пытаться загрузить сборку App.WPF.Win10, если она действительно не нужна, то есть ОС времени выполнения Windows 10 TH1 +.

Создание нескольких сборок и MSI для Win 10 и других - это то, что я хотел бытакже хотел бы избежать.

...