Skip to content

Commit f429687

Browse files
committed
Introduce AppNotificationManager::Register API to take in assets
1 parent 86fbd6c commit f429687

9 files changed

Lines changed: 291 additions & 31 deletions

File tree

dev/AppNotifications/AppNotificationManager.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <winrt/Windows.Foundation.Collections.h>
2222
#include <WindowsAppRuntime.SelfContained.h>
2323
#include <ShellLocalization.h>
24+
#include <filesystem>
2425

2526
using namespace std::literals;
2627

@@ -93,7 +94,7 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
9394
return m_activatedEventArgs;
9495
}
9596

96-
void AppNotificationManager::Register()
97+
void AppNotificationManager::RegisterHelper(hstring const& displayName, std::wstring const& iconFilePath)
9798
{
9899
HRESULT hr{ S_OK };
99100

@@ -122,7 +123,7 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
122123
{
123124
THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(m_appId.c_str(), GUID_NULL));
124125

125-
storedComActivatorGuid = RegisterComActivatorGuidAndAssets();
126+
storedComActivatorGuid = RegisterComActivatorGuidAndAssets(displayName, iconFilePath);
126127
}
127128

128129
if (!WindowsAppRuntime::SelfContained::IsSelfContained())
@@ -167,6 +168,28 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
167168
}
168169
}
169170

171+
void AppNotificationManager::Register()
172+
{
173+
RegisterHelper(winrt::hstring{} /* displayName */, std::wstring{} /* iconFilePath */);
174+
}
175+
176+
void AppNotificationManager::Register(hstring const& displayName, winrt::Uri const& iconUri)
177+
{
178+
THROW_HR_IF_MSG(E_ILLEGAL_METHOD_CALL, AppModel::Identity::IsPackagedProcess(), "Not applicable for packaged applications");
179+
180+
THROW_HR_IF(E_INVALIDARG, (displayName != winrt::hstring{}) xor (iconUri != nullptr));
181+
182+
std::wstring iconFilePath{};
183+
if (iconUri != nullptr)
184+
{
185+
iconFilePath = iconUri.Path();
186+
iconFilePath = iconFilePath.substr(1, iconFilePath.size() - 1);
187+
winrt::check_bool(std::filesystem::exists(std::filesystem::path{ iconFilePath }));
188+
}
189+
190+
RegisterHelper(displayName, iconFilePath);
191+
}
192+
170193
// This assumes that the caller has taken an exclusive lock
171194
void AppNotificationManager::UnregisterHelper()
172195
{
@@ -307,7 +330,7 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
307330
}
308331
else
309332
{
310-
registeredClsid = RegisterComActivatorGuidAndAssets();
333+
registeredClsid = RegisterComActivatorGuidAndAssets(winrt::hstring{} /* displayName */, nullptr /* iconUri */);
311334
}
312335

313336
auto notificationCallback{ winrt::create_instance<INotificationActivationCallback>(registeredClsid, CLSCTX_ALL) };

dev/AppNotifications/AppNotificationManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
1818

1919
static winrt::Microsoft::Windows::AppNotifications::AppNotificationManager Default();
2020
static winrt::Windows::Foundation::IInspectable AppNotificationDeserialize(winrt::Windows::Foundation::Uri const& uri);
21+
22+
void Register(hstring const& displayName, winrt::Windows::Foundation::Uri const& iconUri);
2123
void Register();
2224
void Unregister();
2325
void UnregisterAll();
@@ -45,6 +47,7 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
4547
winrt::Windows::Foundation::IInspectable Deserialize(winrt::Windows::Foundation::Uri const& uri);
4648
private:
4749

50+
void RegisterHelper(hstring const& displayName, std::wstring const& iconFilePath);
4851
void UnregisterHelper();
4952

5053
wil::unique_com_class_object_cookie m_notificationComActivatorRegistration;

dev/AppNotifications/AppNotificationUtility.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ std::wstring Microsoft::Windows::AppNotifications::Helpers::GetDisplayNameBasedO
241241
return displayName;
242242
}
243243

244-
winrt::guid Microsoft::Windows::AppNotifications::Helpers::RegisterComActivatorGuidAndAssets()
244+
winrt::guid Microsoft::Windows::AppNotifications::Helpers::RegisterComActivatorGuidAndAssets(winrt::hstring const& displayName, std::wstring const& iconFilePath)
245245
{
246246
std::wstring registeredGuid;
247247
auto hr = GetActivatorGuid(registeredGuid);
@@ -258,20 +258,42 @@ winrt::guid Microsoft::Windows::AppNotifications::Helpers::RegisterComActivatorG
258258
RegisterComServer(comActivatorGuidString);
259259

260260
registeredGuid = comActivatorGuidString.get();
261+
std::wstring notificationAppId{ Microsoft::Windows::AppNotifications::Helpers::RetrieveNotificationAppId() };
262+
RegisterAssets(notificationAppId, registeredGuid, displayName, iconFilePath);
261263
}
262264
else
263265
{
264266
THROW_IF_FAILED(hr);
265267
}
266268

267-
std::wstring notificationAppId{ Microsoft::Windows::AppNotifications::Helpers::RetrieveNotificationAppId() };
268-
RegisterAssets(notificationAppId, registeredGuid);
269-
270269
// Remove braces around the guid string
271270
return winrt::guid(registeredGuid.substr(1, registeredGuid.size() - 2));
272271
}
273272

274-
void Microsoft::Windows::AppNotifications::Helpers::RegisterAssets(std::wstring const& appId, std::wstring const& clsid)
273+
// Try the following techniques to retrieve display name and icon:
274+
// 1. Assets provided by the user
275+
// 2. Based on the best app shortcut, using the FrameworkUdk.
276+
// 3. From the current process.
277+
// 4. Set a default DisplayName, but leave empty the icon file path so Shell can set a default icon.
278+
Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets Microsoft::Windows::AppNotifications::Helpers::RegisterAssetsHelper(winrt::hstring const& displayName, std::wstring const& iconFilePath)
279+
{
280+
Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets assets{};
281+
282+
if ((!displayName.empty()) && (!iconFilePath.empty()))
283+
{
284+
assets.displayName = displayName.c_str();
285+
assets.iconFilePath = iconFilePath.c_str();
286+
}
287+
else if (FAILED(Microsoft::Windows::AppNotifications::ShellLocalization::RetrieveAssetsFromShortcut(assets)) &&
288+
FAILED(Microsoft::Windows::AppNotifications::ShellLocalization::RetrieveAssetsFromProcess(assets)))
289+
{
290+
assets.displayName = GetDisplayNameBasedOnProcessName();
291+
}
292+
293+
return assets;
294+
}
295+
296+
void Microsoft::Windows::AppNotifications::Helpers::RegisterAssets(std::wstring const& appId, std::wstring const& clsid, winrt::hstring const& displayName, std::wstring const& iconFilePath)
275297
{
276298
wil::unique_hkey hKey;
277299
// subKey: \Software\Classes\AppUserModelId\{AppGUID}
@@ -288,17 +310,7 @@ void Microsoft::Windows::AppNotifications::Helpers::RegisterAssets(std::wstring
288310
&hKey,
289311
nullptr /* lpdwDisposition */));
290312

291-
// Try the following techniques to retrieve display name and icon:
292-
// 1. Based on the best app shortcut, using the FrameworkUdk.
293-
// 2. From the current process.
294-
// 3. Set a default DisplayName, but leave empty the icon file path so Shell can set a default icon.
295-
Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets assets{};
296-
297-
if (FAILED(Microsoft::Windows::AppNotifications::ShellLocalization::RetrieveAssetsFromShortcut(assets)) &&
298-
FAILED(Microsoft::Windows::AppNotifications::ShellLocalization::RetrieveAssetsFromProcess(assets)))
299-
{
300-
assets.displayName = GetDisplayNameBasedOnProcessName();
301-
}
313+
Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets assets{ RegisterAssetsHelper(displayName, iconFilePath) };
302314

303315
RegisterValue(hKey, L"DisplayName", reinterpret_cast<const BYTE*>(assets.displayName.c_str()), REG_EXPAND_SZ, assets.displayName.size() * sizeof(wchar_t));
304316

dev/AppNotifications/AppNotificationUtility.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <wil/resource.h>
99
#include <AppNotificationActivatedEventArgs.h>
1010
#include <FrameworkUdk/toastnotificationsrt.h>
11+
#include <ShellLocalization.h>
1112

1213
namespace Microsoft::Windows::AppNotifications::Helpers
1314
{
@@ -53,13 +54,15 @@ namespace Microsoft::Windows::AppNotifications::Helpers
5354

5455
HRESULT GetActivatorGuid(std::wstring& activatorGuid) noexcept;
5556

56-
winrt::guid RegisterComActivatorGuidAndAssets();
57+
winrt::guid RegisterComActivatorGuidAndAssets(winrt::hstring const& displayName, std::wstring const& iconFilePath);
5758

58-
void RegisterAssets(std::wstring const& appId, std::wstring const& clsid);
59+
void RegisterAssets(std::wstring const& appId, std::wstring const& clsid, winrt::hstring const& displayName, std::wstring const& iconFilePath);
5960

6061
wil::unique_cotaskmem_string ConvertUtf8StringToWideString(unsigned long length, const BYTE* utf8String);
6162

6263
winrt::Microsoft::Windows::AppNotifications::AppNotification ToastNotificationFromToastProperties(ABI::Microsoft::Internal::ToastNotifications::INotificationProperties* properties);
6364

6465
std::wstring GetDisplayNameBasedOnProcessName();
66+
67+
Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets RegisterAssetsHelper(winrt::hstring const& displayName, std::wstring const& iconFilePath);
6568
}

dev/AppNotifications/AppNotifications.idl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ namespace Microsoft.Windows.AppNotifications
117117
// For Unpackaged apps, the caller process will be registered as the COM server. And assets like displayname and icon will be gleaned from Shell and registered as well.
118118
void Register();
119119

120+
// For Unpackaged apps only, the caller process will be registered as the COM server and assets registered.
121+
void Register(String displayName, Windows.Foundation.Uri iconUri);
122+
120123
// Unregisters the COM Service so that a subsequent activation will launch a new process
121124
void Unregister();
122125

dev/AppNotifications/ShellLocalization.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,7 @@ HRESULT Microsoft::Windows::AppNotifications::ShellLocalization::DeleteIconFromC
258258
std::path iconFilePath{ RetrieveLocalFolderPath() / (notificationAppId + c_pngExtension) };
259259

260260
// If DeleteFile returned FALSE, then deletion failed and we should return the corresponding error code.
261-
if (DeleteFile(iconFilePath.c_str()) == FALSE)
262-
{
263-
THROW_HR(HRESULT_FROM_WIN32(GetLastError()));
264-
}
261+
winrt::check_bool(DeleteFile(iconFilePath.c_str()) != FALSE);
265262

266263
return S_OK;
267264
}

dev/Common/Common.vcxitems.filters

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
<ClInclude Include="$(MSBuildThisFileDirectory)WindowsAppRuntime.SelfContained.h">
2727
<Filter>Header Files</Filter>
2828
</ClInclude>
29-
<ClInclude Include="$(MSBuildThisFileDirectory)WindowsAppRuntime.VersionInfo.h">
30-
<Filter>Header Files</Filter>
31-
</ClInclude>
3229
<ClInclude Include="$(MSBuildThisFileDirectory)Security.IntegrityLevel.h">
3330
<Filter>Header Files</Filter>
3431
</ClInclude>
3532
<ClInclude Include="$(MSBuildThisFileDirectory)Microsoft.Foundation.String.h">
3633
<Filter>Header Files</Filter>
3734
</ClInclude>
35+
<ClInclude Include="$(MSBuildThisFileDirectory)WindowsAppRuntime.VersionInfo.h">
36+
<Filter>Header Files</Filter>
37+
</ClInclude>
3838
</ItemGroup>
3939
<ItemGroup>
4040
<ClCompile Include="$(MSBuildThisFileDirectory)WindowsAppRuntime.SelfContained.cpp">
@@ -44,4 +44,4 @@
4444
<Filter>Source Files</Filter>
4545
</ClCompile>
4646
</ItemGroup>
47-
</Project>
47+
</Project>

0 commit comments

Comments
 (0)