Как самостоятельно зарегистрировать приложение WPF C# для рабочего стола (распространяется как exe) для локальных всплывающих уведомлений? - PullRequest
2 голосов
/ 20 июня 2020

У нас есть настольное приложение Windows (написанное на WFP / C#), которое мы распространяем как один файл .exe без установщика (оно объединяет все свои зависимости через плагин Fody / Costura).

Мы хотели бы интегрировать локальную функциональность всплывающих окон Центра действий, где приложение может отображать всплывающее уведомление и отвечать на него при нажатии.

Отображение всплывающего сообщения является простым и может быть выполнено с помощью Microsoft.Toolkit. Пакет nuget Uwp.Notifications. Однако для того, чтобы действительно получать правильные уведомления при щелчке тоста в Центре действий (в отличие от всплывающей подсказки), нам необходимо зарегистрироваться на платформе уведомлений.

Руководство о том, как это сделать, похоже, сосредоточены на приложениях с установщиком (например, Wix): https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast-desktop?fbclid=IwAR2AoHRKI88VNGRG-pTUytwhkMuovWT4bEr0RoXEayWpWsoGlghtZeq4Mo4#step -4-register-with-notification-platform

Специфическая задача c, которую мы пытаемся решить: из документации:

Если вы используете classi c Win32 (или если вы поддерживаете оба), вы должны объявить свой идентификатор модели пользователя приложения (AUMID) и CLSID активатора всплывающих окон (GUID из шага № 3) на ярлыке вашего приложения в меню «Пуск».

Как это сделать, не написав установщик? Мы хотели бы, чтобы наше приложение выполняло эту регистрацию при первом запуске.

Примечание: приложение уже имеет условия для повышения себя через UA C, если это необходимо, путем перезапуска в контексте администратора.

Дополнительные ссылки: WPF native windows 10 тостов

[ Обновление ]

Мне удалось выполнить инструкции в https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast-desktop и https://docs.microsoft.com/en-us/windows/win32/shell/enable-desktop-toast-with-appusermodelid, чтобы собрать то, что должно было быть рабочим решением, но, в конце концов, нажатие на тосты в Центре действий не вызывает OnActivated () в моем NotificationActivatior .

Основные моменты:

  1. Отправка уведомления

    var toast = new ToastNotification(toastXml);
    DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
    
  2. Регистрация:

    string shortcutPath = Path.Combine(
      Environment.GetFolderPath(Environment.SpecialFolder.Programs),
      "Toasty.lnk");
    
    DesktopNotificationManagerCompat.RegisterAumidAndComServer
      <MyNotificationActivator>(AppName);
    
    DesktopNotificationManagerCompat.RegisterActivator
      <MyNotificationActivator>();
    
    if (!File.Exists(shortcutPath))
    {
      ShortcutManager.RegisterAppForNotifications(
        shortcutPath,
        Assembly.GetExecutingAssembly().Location,
        null,
        AppName,
        ActivationId);
     }
    
  3. Создание ярлыка

    public static void RegisterAppForNotifications(
      string shortcutPath,
      string appExecutablePath,
      string arguments,
      string appName,
      string activatorId)
    {
      var shellLinkClass = new ShellLinkCoClass();
      IShellLinkW shellLink = (IShellLinkW)shellLinkClass;
      shellLink.SetPath(appExecutablePath);
    
      IPropertyStore propertyStore = (IPropertyStore)shellLinkClass;
      IPersistFile persistFile = (IPersistFile)shellLinkClass;
    
      if (arguments != null)
      {
        shellLink.SetArguments(arguments);
      }
            
      // https://docs.microsoft.com/en-us/windows/win32/properties/props-system-appusermodel-id
      propertyStore.SetValue(
          new PropertyKey("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3", 5),
          new PROPVARIANT(appName));
    
       // https://docs.microsoft.com/en-us/windows/win32/properties/props-system-appusermodel-toastactivatorclsid
       propertyStore.SetValue(
         new PropertyKey("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3", 26),
         new PROPVARIANT(new Guid(activatorId)));
       propertyStore.Commit();
    
       persistFile.Save(shortcutPath, true);
    }

[ Обновление ]

Наконец-то он заработал - не уверен, что случилось раньше, но финальная версия вроде бы в порядке. Полный код: https://gist.github.com/davidair/c4ea207bf6eece4ef08b97ab29a3036f

1 Ответ

0 голосов
/ 25 июня 2020

У меня сейчас та же проблема с моим проектом.

Удалось найти этот репозиторий - https://github.com/felixrieseberg/electron-windows-interactive-notifications

Вот реализация C ++ для установки ярлыка (файл InteractiveNotifications, InstallShortcut метод). Думаю, проблема в том, как мы устанавливаем значение PropertyStore, строка GUID по какой-то причине не подходит. Тем не менее, я пока не смог решить проблему.

ОБНОВЛЕНО: Наконец, удалось установить ярлык из кода! Посмотрите мой пример на Github. https://github.com/romayavorskyi/WpfNotificationTest (все еще много жесткого кода, но он должен дать вам общее представление). И вы были правы, кратчайший путь имеет значение. Кажется, для корректной работы ярлык должен находиться в папке ProgramData.

...