У нас есть настольное приложение 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 .
Основные моменты:
Отправка уведомления
var toast = new ToastNotification(toastXml);
DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
Регистрация:
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);
}
Создание ярлыка
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