Skip to content

Commit 2854c78

Browse files
committed
re-register OpenWithProgids at startup if installed
This restores SumatraPDF in the 'Open with' context menu for .pdf (and other supported formats) in case another app (e.g. Microsoft Edge) has removed the entry after taking over the default handler.
1 parent 1272e5b commit 2854c78

3 files changed

Lines changed: 60 additions & 0 deletions

File tree

src/Installer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,5 @@ bool WriteExtendedFileExtensionInfo(HKEY hkey, const char* installedExePat);
9292
bool RemoveUninstallerRegistryInfo(HKEY hkey);
9393
void RemoveInstallRegistryKeys(HKEY hkey);
9494
int GetInstallerWinDx();
95+
96+
void ReRegisterFileAssociations();

src/RegistryInstaller.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ static void ShellNotifyAssociationsChanged() {
3232
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
3333
}
3434

35+
static bool HasRegistryValue(HKEY hkey, const char* keyName, const char* valName) {
36+
WCHAR* keyW = ToWStrTemp(keyName);
37+
WCHAR* valW = ToWStrTemp(valName);
38+
DWORD type = 0;
39+
DWORD cb = 0;
40+
LSTATUS res = SHGetValueW(hkey, keyW, valW, &type, nullptr, &cb);
41+
// success or ERROR_MORE_DATA means the value exists
42+
return (res == ERROR_SUCCESS || res == ERROR_MORE_DATA);
43+
}
44+
45+
static bool HasOurOpenWithEntry(HKEY hkey, const char* ext) {
46+
TempStr key = str::JoinTemp("Software\\Classes\\", ext, "\\OpenWithProgids");
47+
TempStr progID = str::JoinTemp(kAppName, ext);
48+
return HasRegistryValue(hkey, key, progID);
49+
}
50+
3551
// caller needs to str::Free() the result
3652
static char* GetInstallDate() {
3753
SYSTEMTIME st;
@@ -635,3 +651,44 @@ void RemoveInstallRegistryKeys(HKEY hkey) {
635651

636652
ShellNotifyAssociationsChanged();
637653
}
654+
655+
// re-register our "Open With" file association handlers (under OpenWithProgids
656+
// and the corresponding ProgID entries) if this is an installed (non-portable)
657+
// copy of SumatraPDF. We do this at startup to counter other apps (e.g. Microsoft
658+
// Edge) that might remove us from the "Open with" context menu for .pdf etc. files.
659+
// We only touch HKCU (always writable by the current user) and optionally HKLM
660+
// (for all-users installs; fails gracefully without admin rights).
661+
void ReRegisterFileAssociations() {
662+
if (!IsOurExeInstalled()) {
663+
return;
664+
}
665+
TempStr exePath = GetSelfExePathTemp();
666+
if (str::IsEmpty(exePath)) {
667+
return;
668+
}
669+
670+
bool didRegister = false;
671+
if (!HasOurOpenWithEntry(HKEY_CURRENT_USER, ".pdf")) {
672+
RegisterForOpenWith(HKEY_CURRENT_USER, exePath);
673+
if (IsWindows10OrGreater()) {
674+
RegisterForDefaultPrograms(HKEY_CURRENT_USER, exePath);
675+
}
676+
didRegister = true;
677+
}
678+
679+
// for all-users installs, also try to restore the HKLM entries (best effort)
680+
TempStr regPathUninst = GetRegPathUninstTemp(kAppName);
681+
if (HasRegistryValue(HKEY_LOCAL_MACHINE, regPathUninst, "InstallLocation")) {
682+
if (!HasOurOpenWithEntry(HKEY_LOCAL_MACHINE, ".pdf")) {
683+
RegisterForOpenWith(HKEY_LOCAL_MACHINE, exePath);
684+
if (IsWindows10OrGreater()) {
685+
RegisterForDefaultPrograms(HKEY_LOCAL_MACHINE, exePath);
686+
}
687+
didRegister = true;
688+
}
689+
}
690+
691+
if (didRegister) {
692+
ShellNotifyAssociationsChanged();
693+
}
694+
}

src/SumatraStartup.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,6 +1510,7 @@ int APIENTRY WinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE, _In_ LPST
15101510
}
15111511

15121512
DetectExternalViewers();
1513+
ReRegisterFileAssociations();
15131514

15141515
gRenderCache = new RenderCache();
15151516

0 commit comments

Comments
 (0)