static void RemoveOwnRegistryKeys() { HKEY keys[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; // remove all keys from both HKLM and HKCU (wherever they exist) for (int i = 0; i < dimof(keys); i++) { UnregisterFromBeingDefaultViewer(keys[i]); DeleteRegKey(keys[i], REG_CLASSES_APP); DeleteRegKey(keys[i], REG_CLASSES_APPS); SHDeleteValue(keys[i], REG_CLASSES_PDF L"\\OpenWithProgids", TAPP); for (int j = 0; NULL != gSupportedExts[j]; j++) { ScopedMem<WCHAR> keyname(str::Join(L"Software\\Classes\\", gSupportedExts[j], L"\\OpenWithProgids")); SHDeleteValue(keys[i], keyname, TAPP); DeleteEmptyRegKey(keys[i], keyname); keyname.Set(str::Join(L"Software\\Classes\\", gSupportedExts[j], L"\\OpenWithList\\" EXENAME)); if (!DeleteRegKey(keys[i], keyname)) continue; // remove empty keys that the installer might have created *(WCHAR *)str::FindCharLast(keyname, '\\') = '\0'; if (!DeleteEmptyRegKey(keys[i], keyname)) continue; *(WCHAR *)str::FindCharLast(keyname, '\\') = '\0'; DeleteEmptyRegKey(keys[i], keyname); } } }
/* Undo what DoAssociateExeWithPdfExtension() in AppTools.cpp did */ static void UnregisterFromBeingDefaultViewer(HKEY hkey) { ScopedMem<WCHAR> curr(ReadRegStr(hkey, REG_CLASSES_PDF, NULL)); ScopedMem<WCHAR> prev(ReadRegStr(hkey, REG_CLASSES_APP, L"previous.pdf")); if (!curr || !str::Eq(curr, TAPP)) { // not the default, do nothing } else if (prev) { WriteRegStr(hkey, REG_CLASSES_PDF, NULL, prev); } else { SHDeleteValue(hkey, REG_CLASSES_PDF, NULL); } // the following settings overrule HKEY_CLASSES_ROOT\.pdf ScopedMem<WCHAR> buf(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, PROG_ID)); if (str::Eq(buf, TAPP)) { LONG res = SHDeleteValue(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, PROG_ID); if (res != ERROR_SUCCESS) LogLastError(res); } buf.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, APPLICATION)); if (str::EqI(buf, EXENAME)) { LONG res = SHDeleteValue(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, APPLICATION); if (res != ERROR_SUCCESS) LogLastError(res); } buf.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", PROG_ID)); if (str::Eq(buf, TAPP)) DeleteRegKey(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", true); }
/* Undo what DoAssociateExeWithPdfExtension() in AppTools.cpp did */ static void UnregisterFromBeingDefaultViewer(HKEY hkey) { ScopedMem<WCHAR> curr(ReadRegStr(hkey, REG_CLASSES_PDF, nullptr)); ScopedMem<WCHAR> prev(ReadRegStr(hkey, REG_CLASSES_APP, L"previous.pdf")); if (!curr || !str::Eq(curr, APP_NAME_STR)) { // not the default, do nothing } else if (prev) { WriteRegStr(hkey, REG_CLASSES_PDF, nullptr, prev); } else { #pragma warning(push) #pragma warning(disable : 6387) // silence /analyze: '_Param_(3)' could be '0': this does not adhere to the specification for the function 'SHDeleteValueW' SHDeleteValue(hkey, REG_CLASSES_PDF, nullptr); #pragma warning(pop) } // the following settings overrule HKEY_CLASSES_ROOT\.pdf ScopedMem<WCHAR> buf(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, PROG_ID)); if (str::Eq(buf, APP_NAME_STR)) { LONG res = SHDeleteValue(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, PROG_ID); if (res != ERROR_SUCCESS) LogLastError(res); } buf.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, APPLICATION)); if (str::EqI(buf, EXENAME)) { LONG res = SHDeleteValue(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT, APPLICATION); if (res != ERROR_SUCCESS) LogLastError(res); } buf.Set(ReadRegStr(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", PROG_ID)); if (str::Eq(buf, APP_NAME_STR)) DeleteRegKey(HKEY_CURRENT_USER, REG_EXPLORER_PDF_EXT L"\\UserChoice", true); }
static int uninstall_tox() { if (MessageBox(NULL, "Are you sure you want to uninstall uTox?", "uTox Updater", MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND) == IDYES) { wchar_t wsz[MAX_PATH + 64]; if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, wsz))) { wcscat(wsz, L"\\Programs\\Tox.lnk"); DeleteFileW(wsz); } if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, wsz))) { wcscat(wsz, L"\\Tox.lnk"); DeleteFileW(wsz); } SHDeleteKey(HKEY_CURRENT_USER, "Software\\Classes\\tox"); SHDeleteKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\uTox"); SHDeleteValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "uTox"); DeleteFile(TOX_EXE_NAME); DeleteFile(TOX_VERSION_FILENAME); MessageBox(main_window, "uTox uninstalled.", "uTox Updater", MB_OK | MB_SETFOREGROUND); } exit(0); }
static BOOL RemoveMyDriver() { char buf[300]; DWORD usagecount; DWORD valtype, valsize, rc; /* most of this is equivalent to what SQLRemoveDriver is suppposed to do, except that it consistently causes a crash, so we do it ourselves */ snprintf(buf, sizeof(buf), "SOFTWARE\\ODBC\\ODBCINST.INI\\%s", DriverName); valsize = sizeof(usagecount); usagecount = 0; valtype = REG_DWORD; rc = SHGetValue(HKEY_LOCAL_MACHINE, buf, "UsageCount", &valtype, &usagecount, &valsize); if (rc == ERROR_FILE_NOT_FOUND) { /* not installed, do nothing */ exit(0); } if (rc != ERROR_SUCCESS) { ProcessSysErrorMessage(rc, "one"); return FALSE; } if (usagecount > 1) { usagecount--; rc = SHSetValue(HKEY_LOCAL_MACHINE, buf, "UsageCount", REG_DWORD, &usagecount, sizeof(usagecount)); if (rc != ERROR_SUCCESS) { ProcessSysErrorMessage(rc, "two"); return FALSE; } return TRUE; } rc = SHDeleteKey(HKEY_LOCAL_MACHINE, buf); if (rc != ERROR_SUCCESS) { ProcessSysErrorMessage(rc, "three"); return FALSE; } rc = SHDeleteValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers", DriverName); if (rc != ERROR_SUCCESS) { ProcessSysErrorMessage(rc, "four"); return FALSE; } return TRUE; }
DLLEXPORT STDAPI DllUnregisterServer(VOID) { ScopedMem<WCHAR> mozPluginPath(ReadRegStr(HKEY_CURRENT_USER, L"Environment", L"MOZ_PLUGIN_PATH")); if (mozPluginPath) { WCHAR szModulePath[MAX_PATH]; GetModuleFileName(g_hInstance, szModulePath, MAX_PATH); if (str::StartsWithI(szModulePath, mozPluginPath)) SHDeleteValue(HKEY_CURRENT_USER, L"Environment", L"MOZ_PLUGIN_PATH"); } DeleteRegKey(HKEY_LOCAL_MACHINE, g_lpRegKey); if (!DeleteRegKey(HKEY_CURRENT_USER, g_lpRegKey)) return E_UNEXPECTED; return S_OK; }
void DoAssociateExeWithPdfExtension(HKEY hkey) { ScopedMem<WCHAR> exePath(GetExePath()); if (!exePath) return; ScopedMem<WCHAR> prevHandler(nullptr); // Remember the previous default app for the Uninstaller prevHandler.Set(ReadRegStr(hkey, REG_CLASSES_PDF, nullptr)); if (prevHandler && !str::Eq(prevHandler, APP_NAME_STR)) WriteRegStr(hkey, REG_CLASSES_APP, L"previous.pdf", prevHandler); WriteRegStr(hkey, REG_CLASSES_APP, nullptr, _TR("PDF Document")); WCHAR *icon_path = str::Join(exePath, L",1"); WriteRegStr(hkey, REG_CLASSES_APP L"\\DefaultIcon", nullptr, icon_path); free(icon_path); WriteRegStr(hkey, REG_CLASSES_APP L"\\shell", nullptr, L"open"); ScopedMem<WCHAR> cmdPath(str::Format(L"\"%s\" \"%%1\" %%*", exePath.Get())); // "${exePath}" "%1" %* bool ok = WriteRegStr(hkey, REG_CLASSES_APP L"\\shell\\open\\command", nullptr, cmdPath); // also register for printing cmdPath.Set(str::Format(L"\"%s\" -print-to-default \"%%1\"", exePath.Get())); // "${exePath}" -print-to-default "%1" WriteRegStr(hkey, REG_CLASSES_APP L"\\shell\\print\\command", nullptr, cmdPath); // also register for printing to specific printer cmdPath.Set(str::Format(L"\"%s\" -print-to \"%%2\" \"%%1\"", exePath.Get())); // "${exePath}" -print-to "%2" "%1" WriteRegStr(hkey, REG_CLASSES_APP L"\\shell\\printto\\command", nullptr, cmdPath); // Only change the association if we're confident, that we've registered ourselves well enough if (!ok) return; WriteRegStr(hkey, REG_CLASSES_PDF, nullptr, APP_NAME_STR); // TODO: also add SumatraPDF to the Open With lists for the other supported extensions? WriteRegStr(hkey, REG_CLASSES_PDF L"\\OpenWithProgids", APP_NAME_STR, L""); if (hkey == HKEY_CURRENT_USER) { WriteRegStr(hkey, REG_EXPLORER_PDF_EXT, L"Progid", APP_NAME_STR); CrashIf(hkey == 0); // to appease prefast SHDeleteValue(hkey, REG_EXPLORER_PDF_EXT, L"Application"); DeleteRegKey(hkey, REG_EXPLORER_PDF_EXT L"\\UserChoice", true); } }