master
cpp 205 lines 6.64 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 notifications.cpp
8
9 Abstract:
10
11 This file contains notification function definitions.
12
13 --*/
14
15 #include "precomp.h"
16 #include <windows.ui.notifications.h>
17 #include <NotificationActivationCallback.h>
18 #include <appmodel.h>
19 #include <wrl\wrappers\corewrappers.h>
20
21 using namespace ABI::Windows::Data::Xml::Dom;
22 using namespace ABI::Windows::UI::Notifications;
23 using namespace Microsoft::WRL;
24 using namespace Microsoft::WRL::Wrappers;
25
26 using wsl::shared::Localization;
27
28 namespace {
29 HRESULT CreateToastNotifier(IToastNotifier** notifier)
30 {
31 ComPtr<IToastNotificationManagerStatics> toastStatics;
32 RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory(
33 HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), &toastStatics));
34
35 return toastStatics->CreateToastNotifierWithId(HStringReference(L"Microsoft.WSL").Get(), notifier);
36 }
37
38 HRESULT CreateXmlDocumentFromString(const wchar_t* xmlString, IXmlDocument** doc)
39 {
40 ComPtr<IXmlDocument> answer;
41 RETURN_IF_FAILED(Windows::Foundation::ActivateInstance(HStringReference(RuntimeClass_Windows_Data_Xml_Dom_XmlDocument).Get(), &answer));
42
43 ComPtr<IXmlDocumentIO> docIO;
44 RETURN_IF_FAILED(answer.As(&docIO));
45
46 RETURN_IF_FAILED(docIO->LoadXml(HStringReference(xmlString).Get()));
47
48 return answer.CopyTo(doc);
49 }
50
51 HRESULT CreateToastNotification(IXmlDocument* content, IToastNotification** notification)
52 {
53 ComPtr<IToastNotificationFactory> factory;
54 RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory(
55 HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &factory));
56
57 return factory->CreateToastNotification(content, notification);
58 }
59
60 HRESULT DisplayNotification(IXmlDocument* doc)
61 {
62 // Create the notifier
63 // Classic Win32 apps MUST use the compat method to create the notifier
64 wil::com_ptr<IToastNotifier> notifier;
65 RETURN_IF_FAILED(CreateToastNotifier(&notifier));
66
67 // Create the notification itself (using helper method from compat library)
68 wil::com_ptr<IToastNotification> toast;
69 RETURN_IF_FAILED(CreateToastNotification(doc, &toast));
70
71 // And show it!
72 return notifier->Show(toast.get());
73 }
74 } // namespace
75
76 namespace wsl::windows::common::notifications {
77 HRESULT DisplayUpdateNotification(const std::wstring& versionString)
78 try
79 {
80 const std::wstring creationString = std::format(
81 LR"(<toast>
82 <visual>
83 <binding template='ToastGeneric'>
84 <text>{}</text>
85 <text>{}</text>
86 </binding>
87 </visual>
88 <actions>
89 <action arguments='{}' content='{}'/>
90 <action arguments='{}' content='{}'/>
91 </actions>
92 </toast>)",
93 Localization::MessageNewWslVersionAvailable(Localization::Options::DontImpersonate),
94 Localization::MessageUpdateToVersion(versionString.c_str(), Localization::Options::DontImpersonate),
95 wslhost::update_arg,
96 Localization::MessageUpdate(Localization::Options::DontImpersonate),
97 wslhost::release_notes_arg,
98 Localization::MessageViewReleaseNotes(Localization::Options::DontImpersonate));
99
100 wil::com_ptr<IXmlDocument> doc{};
101 THROW_IF_FAILED(CreateXmlDocumentFromString(creationString.c_str(), &doc));
102
103 THROW_IF_FAILED(DisplayNotification(doc.get()));
104
105 return S_OK;
106 }
107 CATCH_RETURN()
108
109 HRESULT DisplayFilesystemNotification(_In_ LPCSTR binaryName)
110 try
111 {
112 const std::wstring creationString = std::format(
113 LR"(<toast>
114 <visual>
115 <binding template='ToastGeneric'>
116 <text>{}</text>
117 <text>{}</text>
118 </binding>
119 </visual>
120 <actions>
121 <action arguments='{} {}' content='{}'/>
122 <action arguments='{} {}' content="{}"/>
123 </actions>
124 </toast>)",
125 Localization::MessagePerformanceTip(Localization::Options::DontImpersonate),
126 Localization::MessageProblematicDrvFsUsage(binaryName, Localization::Options::DontImpersonate),
127 wslhost::docs_arg,
128 wslhost::docs_arg_filesystem_url,
129 Localization::MessageViewDocs(Localization::Options::DontImpersonate),
130 wslhost::disable_notification_arg,
131 LXSS_NOTIFICATION_DRVFS_PERF_DISABLED,
132 Localization::MessageDontShowAgain(Localization::Options::DontImpersonate));
133
134 wil::com_ptr<IXmlDocument> doc{};
135 THROW_IF_FAILED(CreateXmlDocumentFromString(creationString.c_str(), &doc));
136
137 THROW_IF_FAILED(DisplayNotification(doc.get()));
138
139 return S_OK;
140 }
141 CATCH_RETURN()
142
143 void DisplayWarningsNotification()
144 try
145 {
146 const std::wstring creationString = std::format(
147 LR"(<toast>
148 <visual>
149 <binding template='ToastGeneric'>
150 <text>{}</text>
151 </binding>
152 </visual>
153 <actions>
154 <action arguments='{}' content='{}'/>
155 </actions>
156 </toast>)",
157 Localization::MessageWarningDuringStartup(),
158 wslhost::event_viewer_arg,
159 Localization::MessageOpenEventViewer());
160
161 wil::com_ptr<IXmlDocument> doc{};
162 THROW_IF_FAILED(CreateXmlDocumentFromString(creationString.c_str(), &doc));
163
164 THROW_IF_FAILED(DisplayNotification(doc.get()));
165 }
166 CATCH_LOG()
167
168 void DisplayOptionalComponentsNotification()
169 try
170 {
171 const std::wstring creationString = std::format(
172 LR"(<toast>
173 <visual>
174 <binding template='ToastGeneric'>
175 <text>{}</text>
176 </binding>
177 </visual>
178 <actions>
179 <action arguments='{}' content='{}'/>
180 </actions>
181 </toast>)",
182 Localization::MessageMissingOptionalComponents(),
183 wslhost::install_prerequisites_arg,
184 Localization::MessageInstallMissingOptionalComponents());
185
186 wil::com_ptr<IXmlDocument> doc{};
187 THROW_IF_FAILED(CreateXmlDocumentFromString(creationString.c_str(), &doc));
188
189 THROW_IF_FAILED(DisplayNotification(doc.get()));
190 }
191 CATCH_LOG()
192
193 void DisplayProxyChangeNotification(const std::wstring& message)
194 try
195 {
196 const std::wstring creationString =
197 std::format(LR"(<toast><visual><binding template='ToastGeneric'><text>{}</text></binding></visual></toast>)", message);
198
199 wil::com_ptr<IXmlDocument> doc{};
200 THROW_IF_FAILED(CreateXmlDocumentFromString(creationString.c_str(), &doc));
201
202 THROW_IF_FAILED(DisplayNotification(doc.get()));
203 }
204 CATCH_LOG()
205 } // namespace wsl::windows::common::notifications