1
0
mirror of https://github.com/valinet/ExplorerPatcher.git synced 2024-11-24 07:30:22 +01:00

Improved delivery of toast notifications

This commit is contained in:
Valentin Radu 2021-11-15 03:59:19 +02:00
parent 2d9158c384
commit f226f1ade6
7 changed files with 424 additions and 75 deletions

View File

@ -29,6 +29,7 @@ Tested on build 22000.318 and 22000.346 (currently in Windows Insider beta and r
* Hardcoded symbols are now based on file hashes, not build numbers * Hardcoded symbols are now based on file hashes, not build numbers
* Better organization for the settings in "Properties" * Better organization for the settings in "Properties"
* Update toast notifications are displayed only as long as they are required. Subsequent notifications no longer have to wait for the previous ones to timeout, but rather they replace the previous ones (#346) (.2)
#### Fixes #### Fixes
@ -41,6 +42,11 @@ Tested on build 22000.318 and 22000.346 (currently in Windows Insider beta and r
* Removed verbose output from "Settings Manager" * Removed verbose output from "Settings Manager"
* Corrected import from `dxgi.dll` * Corrected import from `dxgi.dll`
* Fixed typo in configuration UI (#346) (.1) * Fixed typo in configuration UI (#346) (.1)
* Fixed typos and spelling in error message (#346) (.2)
* Fixed bug that prevented "Properties" from working when invoked from Quick Launch or other toolbars (#349) (.2)
* As you may have noticed, releases do not contain unpacked files anymore. Thus, for people looking for a quick way to get the unpacked files, the release notes now include a link to the artifacts generated during during the build process. The artifacts include the usual DLLs (including `dxgi.dll`), plus symbol files and all the helper executables generated during the build. (#351) (.2)
* Setup program version is synchronized with the version of the application (.2)
* Fixed a mismatch between the default value for the setting "Add shortcut to program settings in Win+X menu" displayed in the UI and actually used in the software (#352) (.2)
## 22000.318.36 ## 22000.318.36

View File

@ -69,6 +69,7 @@ DWORD bNoMenuAccelerator = FALSE;
DWORD bTaskbarMonitorOverride = 0; DWORD bTaskbarMonitorOverride = 0;
DWORD dwIMEStyle = 0; DWORD dwIMEStyle = 0;
DWORD dwTaskbarAl = 0; DWORD dwTaskbarAl = 0;
DWORD bShowUpdateToast = FALSE;
HMODULE hModule = NULL; HMODULE hModule = NULL;
HANDLE hDelayedInjectionThread = NULL; HANDLE hDelayedInjectionThread = NULL;
HANDLE hIsWinXShown = NULL; HANDLE hIsWinXShown = NULL;
@ -137,6 +138,74 @@ HRESULT WINAPI _DllGetClassObject(
#ifdef _WIN64 #ifdef _WIN64
DWORD CheckForUpdatesThread(LPVOID unused) DWORD CheckForUpdatesThread(LPVOID unused)
{ {
HRESULT hr = S_OK;
HSTRING_HEADER header_AppIdHString;
HSTRING AppIdHString = NULL;
HSTRING_HEADER header_ToastNotificationManagerHString;
HSTRING ToastNotificationManagerHString = NULL;
__x_ABI_CWindows_CUI_CNotifications_CIToastNotificationManagerStatics* toastStatics = NULL;
__x_ABI_CWindows_CUI_CNotifications_CIToastNotifier* notifier = NULL;
HSTRING_HEADER header_ToastNotificationHString;
HSTRING ToastNotificationHString = NULL;
__x_ABI_CWindows_CUI_CNotifications_CIToastNotificationFactory* notifFactory = NULL;
__x_ABI_CWindows_CUI_CNotifications_CIToastNotification* toast = NULL;
if (SUCCEEDED(hr))
{
hr = RoInitialize(RO_INIT_MULTITHREADED);
}
if (SUCCEEDED(hr))
{
hr = WindowsCreateStringReference(
APPID,
(UINT32)(sizeof(APPID) / sizeof(TCHAR) - 1),
&header_AppIdHString,
&AppIdHString
);
}
if (SUCCEEDED(hr))
{
hr = WindowsCreateStringReference(
RuntimeClass_Windows_UI_Notifications_ToastNotificationManager,
(UINT32)(sizeof(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager) / sizeof(wchar_t) - 1),
&header_ToastNotificationManagerHString,
&ToastNotificationManagerHString
);
}
if (SUCCEEDED(hr))
{
hr = RoGetActivationFactory(
ToastNotificationManagerHString,
&UIID_IToastNotificationManagerStatics,
(LPVOID*)&toastStatics
);
}
if (SUCCEEDED(hr))
{
hr = toastStatics->lpVtbl->CreateToastNotifierWithId(
toastStatics,
AppIdHString,
&notifier
);
}
if (SUCCEEDED(hr))
{
hr = WindowsCreateStringReference(
RuntimeClass_Windows_UI_Notifications_ToastNotification,
(UINT32)(sizeof(RuntimeClass_Windows_UI_Notifications_ToastNotification) / sizeof(wchar_t) - 1),
&header_ToastNotificationHString,
&ToastNotificationHString
);
}
if (SUCCEEDED(hr))
{
hr = RoGetActivationFactory(
ToastNotificationHString,
&UIID_IToastNotificationFactory,
(LPVOID*)&notifFactory
);
}
HANDLE hEvents[2]; HANDLE hEvents[2];
hEvents[0] = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_CheckForUpdates_" _T(EP_CLSID)); hEvents[0] = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_CheckForUpdates_" _T(EP_CLSID));
hEvents[1] = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_InstallUpdates_" _T(EP_CLSID)); hEvents[1] = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_InstallUpdates_" _T(EP_CLSID));
@ -144,7 +213,7 @@ DWORD CheckForUpdatesThread(LPVOID unused)
{ {
if (dwUpdatePolicy != UPDATE_POLICY_MANUAL) if (dwUpdatePolicy != UPDATE_POLICY_MANUAL)
{ {
InstallUpdatesIfAvailable(UPDATES_OP_DEFAULT, bAllocConsole, dwUpdatePolicy); InstallUpdatesIfAvailable(hModule, bShowUpdateToast, notifier, notifFactory, &toast, UPDATES_OP_DEFAULT, bAllocConsole, dwUpdatePolicy);
} }
DWORD dwRet = 0; DWORD dwRet = 0;
while (TRUE) while (TRUE)
@ -153,12 +222,12 @@ DWORD CheckForUpdatesThread(LPVOID unused)
{ {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
{ {
InstallUpdatesIfAvailable(UPDATES_OP_CHECK, bAllocConsole, dwUpdatePolicy); InstallUpdatesIfAvailable(hModule, bShowUpdateToast, notifier, notifFactory, &toast, UPDATES_OP_CHECK, bAllocConsole, dwUpdatePolicy);
break; break;
} }
case WAIT_OBJECT_0 + 1: case WAIT_OBJECT_0 + 1:
{ {
InstallUpdatesIfAvailable(UPDATES_OP_INSTALL, bAllocConsole, dwUpdatePolicy); InstallUpdatesIfAvailable(hModule, bShowUpdateToast, notifier, notifFactory, &toast, UPDATES_OP_INSTALL, bAllocConsole, dwUpdatePolicy);
break; break;
} }
default: default:
@ -170,6 +239,35 @@ DWORD CheckForUpdatesThread(LPVOID unused)
CloseHandle(hEvents[0]); CloseHandle(hEvents[0]);
CloseHandle(hEvents[1]); CloseHandle(hEvents[1]);
} }
if (toast)
{
toast->lpVtbl->Release(toast);
}
if (notifFactory)
{
notifFactory->lpVtbl->Release(notifFactory);
}
if (ToastNotificationHString)
{
WindowsDeleteString(ToastNotificationHString);
}
if (notifier)
{
notifier->lpVtbl->Release(notifier);
}
if (toastStatics)
{
toastStatics->lpVtbl->Release(toastStatics);
}
if (ToastNotificationManagerHString)
{
WindowsDeleteString(ToastNotificationManagerHString);
}
if (AppIdHString)
{
WindowsDeleteString(AppIdHString);
}
} }
#endif #endif
#pragma endregion #pragma endregion
@ -3288,6 +3386,15 @@ void WINAPI LoadSettings(BOOL bIsExplorer)
&dwUpdatePolicy, &dwUpdatePolicy,
&dwSize &dwSize
); );
dwSize = sizeof(DWORD);
RegQueryValueExW(
hKey,
TEXT("IsUpdatePending"),
0,
NULL,
&bShowUpdateToast,
&dwSize
);
RegCloseKey(hKey); RegCloseKey(hKey);
} }

View File

@ -45,7 +45,7 @@
"TaskbarSD"=dword:00000001 "TaskbarSD"=dword:00000001
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher] [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher]
;b Add shortcut to program settings in Win+X menu ;b Add shortcut to program settings in Win+X menu
"PropertiesInWinX"=dword:00000001 "PropertiesInWinX"=dword:00000000
;t ;t
;T System tray ;T System tray
@ -314,7 +314,7 @@
;t ________________________ ;t ________________________
;y Check for updates ;y Check for updates
;;;EP_CHECK_FOR_UPDATES ;;;EP_CHECK_FOR_UPDATES
;y Install latest version ;y Update
;;;EP_INSTALL_UPDATES ;;;EP_INSTALL_UPDATES
;y Read about changes in the latest releases 🡕 ;y Read about changes in the latest releases 🡕
;https://github.com/valinet/ExplorerPatcher/blob/master/CHANGELOG.md ;https://github.com/valinet/ExplorerPatcher/blob/master/CHANGELOG.md

View File

@ -54,7 +54,15 @@ void IsUpdateAvailableHelperCallback(
} }
} }
BOOL IsUpdateAvailableHelper(char* url, char* szCheckAgainst, DWORD dwUpdateTimeout, BOOL* lpFail) BOOL IsUpdateAvailableHelper(
char* url,
char* szCheckAgainst,
DWORD dwUpdateTimeout,
BOOL* lpFail,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotifier* notifier,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotificationFactory* notifFactory,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotification** toast
)
{ {
BOOL bIsUpdateAvailable = FALSE; BOOL bIsUpdateAvailable = FALSE;
@ -234,6 +242,14 @@ BOOL IsUpdateAvailableHelper(char* url, char* szCheckAgainst, DWORD dwUpdateTime
"\", please allow the elevation request.\n" "\", please allow the elevation request.\n"
); );
#endif #endif
if (*toast)
{
notifier->lpVtbl->Hide(notifier, *toast);
(*toast)->lpVtbl->Release((*toast));
(*toast) = NULL;
}
SHELLEXECUTEINFO ShExecInfo = { 0 }; SHELLEXECUTEINFO ShExecInfo = { 0 };
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
@ -354,10 +370,21 @@ BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail)
#ifdef UPDATES_VERBOSE_OUTPUT #ifdef UPDATES_VERBOSE_OUTPUT
printf("[Updates] Update URL: %s\n", szUpdateURL); printf("[Updates] Update URL: %s\n", szUpdateURL);
#endif #endif
return IsUpdateAvailableHelper(szUpdateURL, szCheckAgainst, dwUpdateTimeout, lpFail); return IsUpdateAvailableHelper(
szUpdateURL,
szCheckAgainst,
dwUpdateTimeout,
lpFail,
NULL, NULL, NULL
);
} }
BOOL UpdateProduct(LPCWSTR wszDataStore) BOOL UpdateProduct(
LPCWSTR wszDataStore,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotifier* notifier,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotificationFactory* notifFactory,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotification** toast
)
{ {
HKEY hKey = NULL; HKEY hKey = NULL;
DWORD dwSize = 0; DWORD dwSize = 0;
@ -410,11 +437,108 @@ BOOL UpdateProduct(LPCWSTR wszDataStore)
#ifdef UPDATES_VERBOSE_OUTPUT #ifdef UPDATES_VERBOSE_OUTPUT
printf("[Updates] Update URL: %s\n", szUpdateURL); printf("[Updates] Update URL: %s\n", szUpdateURL);
#endif #endif
return IsUpdateAvailableHelper(szUpdateURL, NULL, dwUpdateTimeout, NULL); return IsUpdateAvailableHelper(
szUpdateURL,
NULL,
dwUpdateTimeout,
NULL,
notifier,
notifFactory,
toast
);
} }
BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwUpdatePolicy) BOOL InstallUpdatesIfAvailable(
HMODULE hModule,
BOOL bIsPostUpdate,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotifier* notifier,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotificationFactory* notifFactory,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotification** toast,
DWORD dwOperation,
DWORD bAllocConsole,
DWORD dwUpdatePolicy
)
{ {
wchar_t buf[TOAST_BUFSIZ];
DWORD dwLeftMost = 0;
DWORD dwSecondLeft = 0;
DWORD dwSecondRight = 0;
DWORD dwRightMost = 0;
QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost);
if (bIsPostUpdate)
{
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
const wchar_t text[] =
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n"
L" <visual>\r\n"
L" <binding template=\"ToastGeneric\">\r\n"
L" <text><![CDATA[Update successful]]></text>\r\n"
L" <text><![CDATA[Installed version: %d.%d.%d.%d]]></text>\r\n"
L" <text placement=\"attribution\"><![CDATA[ExplorerPatcher]]></text>\r\n"
L" </binding>\r\n"
L" </visual>\r\n"
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n"
L"</toast>\r\n";
swprintf_s(buf, TOAST_BUFSIZ, text, dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost);
String2IXMLDocument(
buf,
wcslen(buf),
&inputXml,
NULL
);
if (*toast)
{
notifier->lpVtbl->Hide(notifier, *toast);
(*toast)->lpVtbl->Release((*toast));
(*toast) = NULL;
}
notifFactory->lpVtbl->CreateToastNotification(notifFactory, inputXml, toast);
if (*toast)
{
notifier->lpVtbl->Show(notifier, *toast);
}
if (inputXml)
{
inputXml->lpVtbl->Release(inputXml);
}
HKEY hKey = NULL;
DWORD dwSize = 0;
RegCreateKeyExW(
HKEY_CURRENT_USER,
TEXT(REGPATH),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WOW64_64KEY | KEY_WRITE,
NULL,
&hKey,
NULL
);
if (hKey == NULL || hKey == INVALID_HANDLE_VALUE)
{
hKey = NULL;
}
if (hKey)
{
dwSize = FALSE;
RegSetValueExW(
hKey,
TEXT("IsUpdatePending"),
0,
REG_DWORD,
&dwSize,
sizeof(DWORD)
);
RegCloseKey(hKey);
}
SwitchToThread();
}
if (bAllocConsole) if (bAllocConsole)
{ {
switch (dwUpdatePolicy) switch (dwUpdatePolicy)
@ -439,44 +563,71 @@ BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwU
} }
} }
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
if (dwOperation == UPDATES_OP_INSTALL) if (dwOperation == UPDATES_OP_INSTALL)
{ {
const wchar_t UpdateAvailableXML[] = const wchar_t text[] =
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" " L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n" L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"long\">\r\n"
L" <visual>\r\n" L" <visual>\r\n"
L" <binding template=\"ToastGeneric\">\r\n" L" <binding template=\"ToastGeneric\">\r\n"
L" <text><![CDATA[Downloading and installing updates]]></text>\r\n" L" <text><![CDATA[Downloading and installing updates]]></text>\r\n"
L" <text><![CDATA[An installation screen will show as soon as the download completes.]]></text>\r\n" L" <text><![CDATA[Installed version: %d.%d.%d.%d]]></text>\r\n"
L" <text placement=\"attribution\"><![CDATA[ExplorerPatcher]]></text>\r\n" L" <text placement=\"attribution\"><![CDATA[ExplorerPatcher]]></text>\r\n"
L" </binding>\r\n" L" </binding>\r\n"
L" </visual>\r\n" L" </visual>\r\n"
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n" L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n"
L"</toast>\r\n"; L"</toast>\r\n";
HRESULT hr = S_OK; swprintf_s(buf, TOAST_BUFSIZ, text, dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost);
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL; String2IXMLDocument(
hr = String2IXMLDocument( buf,
UpdateAvailableXML, wcslen(buf),
wcslen(UpdateAvailableXML),
&inputXml, &inputXml,
#ifdef DEBUG
stdout
#else
NULL NULL
#endif
); );
hr = ShowToastMessage( }
inputXml, else if (dwOperation == UPDATES_OP_CHECK)
APPID, {
sizeof(APPID) / sizeof(TCHAR) - 1, const wchar_t text[] =
#ifdef DEBUG L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
stdout L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"long\">\r\n"
#else L" <visual>\r\n"
L" <binding template=\"ToastGeneric\">\r\n"
L" <text><![CDATA[Checking for updates]]></text>\r\n"
L" <text><![CDATA[Installed version: %d.%d.%d.%d]]></text>\r\n"
L" <text placement=\"attribution\"><![CDATA[ExplorerPatcher]]></text>\r\n"
L" </binding>\r\n"
L" </visual>\r\n"
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n"
L"</toast>\r\n";
swprintf_s(buf, TOAST_BUFSIZ, text, dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost);
String2IXMLDocument(
buf,
wcslen(buf),
&inputXml,
NULL NULL
#endif
); );
} }
if (dwOperation == UPDATES_OP_CHECK || dwOperation == UPDATES_OP_INSTALL)
{
if (*toast)
{
notifier->lpVtbl->Hide(notifier, *toast);
(*toast)->lpVtbl->Release((*toast));
(*toast) = NULL;
}
notifFactory->lpVtbl->CreateToastNotification(notifFactory, inputXml, toast);
if ((*toast))
{
notifier->lpVtbl->Show(notifier, *toast);
}
if (inputXml)
{
inputXml->lpVtbl->Release(inputXml);
}
}
WCHAR dllName[MAX_PATH]; WCHAR dllName[MAX_PATH];
GetModuleFileNameW(hModule, dllName, MAX_PATH); GetModuleFileNameW(hModule, dllName, MAX_PATH);
wprintf(L"[Updates] Path to module: %s\n", dllName); wprintf(L"[Updates] Path to module: %s\n", dllName);
@ -491,11 +642,54 @@ BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwU
printf("[Updates] An update is available.\n"); printf("[Updates] An update is available.\n");
if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_AUTO) || (dwOperation == UPDATES_OP_INSTALL)) if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_AUTO) || (dwOperation == UPDATES_OP_INSTALL))
{ {
UpdateProduct(_T(REGPATH)); __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
BOOL bOk = UpdateProduct(_T(REGPATH), notifier, notifFactory, toast);
if (!bOk)
{
if (dwOperation == UPDATES_OP_INSTALL)
{
const wchar_t text[] =
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n"
L" <visual>\r\n"
L" <binding template=\"ToastGeneric\">\r\n"
L" <text><![CDATA[Update failed]]></text>\r\n"
L" <text><![CDATA[An error occured when attempting to install this update.]]></text>\r\n"
L" <text placement=\"attribution\"><![CDATA[ExplorerPatcher]]></text>\r\n"
L" </binding>\r\n"
L" </visual>\r\n"
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n"
L"</toast>\r\n";
String2IXMLDocument(
text,
wcslen(text),
&inputXml,
NULL
);
}
}
if (bOk || (!bOk && (dwOperation == UPDATES_OP_INSTALL)))
{
if (*toast)
{
notifier->lpVtbl->Hide(notifier, *toast);
(*toast)->lpVtbl->Release((*toast));
(*toast) = NULL;
}
notifFactory->lpVtbl->CreateToastNotification(notifFactory, inputXml, toast);
if ((*toast))
{
notifier->lpVtbl->Show(notifier, *toast);
}
if (inputXml)
{
inputXml->lpVtbl->Release(inputXml);
}
}
} }
else if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_NOTIFY) || (dwOperation == UPDATES_OP_CHECK)) else if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_NOTIFY) || (dwOperation == UPDATES_OP_CHECK))
{ {
const wchar_t UpdateAvailableXML[] = const wchar_t text[] =
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" " L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"long\">\r\n" L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"long\">\r\n"
L" <visual>\r\n" L" <visual>\r\n"
@ -507,28 +701,28 @@ BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwU
L" </visual>\r\n" L" </visual>\r\n"
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n" L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n"
L"</toast>\r\n"; L"</toast>\r\n";
HRESULT hr = S_OK;
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL; __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
hr = String2IXMLDocument( String2IXMLDocument(
UpdateAvailableXML, text,
wcslen(UpdateAvailableXML), wcslen(text),
&inputXml, &inputXml,
#ifdef DEBUG
stdout
#else
NULL NULL
#endif
);
hr = ShowToastMessage(
inputXml,
APPID,
sizeof(APPID) / sizeof(TCHAR) - 1,
#ifdef DEBUG
stdout
#else
NULL
#endif
); );
if (*toast)
{
notifier->lpVtbl->Hide(notifier, *toast);
(*toast)->lpVtbl->Release((*toast));
(*toast) = NULL;
}
notifFactory->lpVtbl->CreateToastNotification(notifFactory, inputXml, toast);
if ((*toast))
{
notifier->lpVtbl->Show(notifier, *toast);
}
if (inputXml)
{
inputXml->lpVtbl->Release(inputXml);
}
} }
return TRUE; return TRUE;
@ -545,7 +739,7 @@ BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwU
} }
if (dwOperation == UPDATES_OP_CHECK || dwOperation == UPDATES_OP_INSTALL) if (dwOperation == UPDATES_OP_CHECK || dwOperation == UPDATES_OP_INSTALL)
{ {
const wchar_t UpdateAvailableXML[] = const wchar_t text[] =
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" " L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n" L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n"
L" <visual>\r\n" L" <visual>\r\n"
@ -557,7 +751,7 @@ BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwU
L" </visual>\r\n" L" </visual>\r\n"
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n" L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n"
L"</toast>\r\n"; L"</toast>\r\n";
const wchar_t UpdateAvailableXML2[] = const wchar_t text2[] =
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" " L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n" L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n"
L" <visual>\r\n" L" <visual>\r\n"
@ -569,28 +763,28 @@ BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwU
L" </visual>\r\n" L" </visual>\r\n"
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n" L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n"
L"</toast>\r\n"; L"</toast>\r\n";
HRESULT hr = S_OK;
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL; __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
hr = String2IXMLDocument( String2IXMLDocument(
bFail ? UpdateAvailableXML2 : UpdateAvailableXML, bFail ? text2 : text,
wcslen(bFail ? UpdateAvailableXML2 : UpdateAvailableXML), wcslen(bFail ? text2 : text),
&inputXml, &inputXml,
#ifdef DEBUG
stdout
#else
NULL NULL
#endif
);
hr = ShowToastMessage(
inputXml,
APPID,
sizeof(APPID) / sizeof(TCHAR) - 1,
#ifdef DEBUG
stdout
#else
NULL
#endif
); );
if (*toast)
{
notifier->lpVtbl->Hide(notifier, *toast);
(*toast)->lpVtbl->Release((*toast));
(*toast) = NULL;
}
notifFactory->lpVtbl->CreateToastNotification(notifFactory, inputXml, toast);
if ((*toast))
{
notifier->lpVtbl->Show(notifier, *toast);
}
if (inputXml)
{
inputXml->lpVtbl->Release(inputXml);
}
} }
return FALSE; return FALSE;
} }

View File

@ -33,7 +33,12 @@ typedef struct IsUpdateAvailableParameters
}; };
BOOL IsUpdatePolicy(LPCWSTR wszDataStore, DWORD dwUpdatePolicy); BOOL IsUpdatePolicy(LPCWSTR wszDataStore, DWORD dwUpdatePolicy);
BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst); BOOL InstallUpdatesIfAvailable(
BOOL UpdateProduct(LPCWSTR wszDataStore); HMODULE hModule,
BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwUpdatePolicy); BOOL bIsPostUpdate,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotifier* notifier,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotificationFactory* notifFactory,
__x_ABI_CWindows_CUI_CNotifications_CIToastNotification** toast,
DWORD dwOperation, DWORD bAllocConsole, DWORD dwUpdatePolicy
);
#endif #endif

View File

@ -29,6 +29,7 @@
#define DOSMODE_OFFSET 78 #define DOSMODE_OFFSET 78
#define SETUP_UTILITY_NAME "ep_setup.exe" #define SETUP_UTILITY_NAME "ep_setup.exe"
#define DEFAULT_UPDATE_URL "https://github.com/valinet/ExplorerPatcher/releases/latest/download/" #define DEFAULT_UPDATE_URL "https://github.com/valinet/ExplorerPatcher/releases/latest/download/"
#define TOAST_BUFSIZ 1024
// This allows compiling with older Windows SDKs as well // This allows compiling with older Windows SDKs as well
#ifndef DWMWA_USE_HOSTBACKDROPBRUSH #ifndef DWMWA_USE_HOSTBACKDROPBRUSH

View File

@ -291,7 +291,7 @@ int WINAPI wWinMain(
_In_ int nShowCmd _In_ int nShowCmd
) )
{ {
BOOL bOk = TRUE, bInstall = TRUE, bWasShellExt = FALSE; BOOL bOk = TRUE, bInstall = TRUE, bWasShellExt = FALSE, bIsUpdate = FALSE;
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
@ -326,6 +326,8 @@ int WINAPI wWinMain(
&argc &argc
); );
bIsUpdate = (argc >= 1 && !_wcsicmp(wargv[0], L"/update_silent"));
WCHAR wszPath[MAX_PATH]; WCHAR wszPath[MAX_PATH];
ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR)); ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR));
if (bOk) if (bOk)
@ -335,7 +337,7 @@ int WINAPI wWinMain(
if (bOk) if (bOk)
{ {
wcscat_s(wszPath, MAX_PATH, L"\\dxgi.dll"); wcscat_s(wszPath, MAX_PATH, L"\\dxgi.dll");
bInstall = !FileExistsW(wszPath) || (argc >= 1 && !_wcsicmp(wargv[0], L"/update_silent")); bInstall = !FileExistsW(wszPath) || bIsUpdate;
} }
if (!bInstall) if (!bInstall)
{ {
@ -498,6 +500,40 @@ int WINAPI wWinMain(
} }
else else
{ {
if (bIsUpdate)
{
HKEY hKey = NULL;
DWORD dwSize = 0;
RegCreateKeyExW(
HKEY_CURRENT_USER,
TEXT(REGPATH),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WOW64_64KEY | KEY_WRITE,
NULL,
&hKey,
NULL
);
if (hKey == NULL || hKey == INVALID_HANDLE_VALUE)
{
hKey = NULL;
}
if (hKey)
{
dwSize = TRUE;
RegSetValueExW(
hKey,
TEXT("IsUpdatePending"),
0,
REG_DWORD,
&dwSize,
sizeof(DWORD)
);
RegCloseKey(hKey);
}
}
//ZZRestartExplorer(0, 0, 0, 0); //ZZRestartExplorer(0, 0, 0, 0);
} }
} }