diff --git a/src/base/system.cpp b/src/base/system.cpp index bf282fbe4..c6f9c19e2 100644 --- a/src/base/system.cpp +++ b/src/base/system.cpp @@ -59,7 +59,7 @@ #define WIN32_LEAN_AND_MEAN #undef _WIN32_WINNT // 0x0501 (Windows XP) is required for mingw to get getaddrinfo to work -// 0x0600 (Windows Vista) is required to use RegGetValueW +// 0x0600 (Windows Vista) is required to use RegGetValueW and RegDeleteTreeW #define _WIN32_WINNT 0x0600 #include #include @@ -4552,6 +4552,33 @@ bool shell_register_extension(const char *extension, const char *description, co return true; } +bool shell_unregister(const char *shell_class, bool *updated) +{ + const std::wstring class_wide = utf8_to_wstring(shell_class); + + // Open registry key for protocol and file associations of the current user + HKEY handle_subkey_classes; + const LRESULT result_subkey_classes = RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes", 0, KEY_ALL_ACCESS, &handle_subkey_classes); + if(result_subkey_classes != ERROR_SUCCESS) + { + windows_print_error("shell_unregister", "Error opening registry key", result_subkey_classes); + return false; + } + + // Delete the registry keys for the shell class (protocol or program ID) + LRESULT result_delete = RegDeleteTreeW(handle_subkey_classes, class_wide.c_str()); + RegCloseKey(handle_subkey_classes); + if(result_delete != ERROR_SUCCESS && result_delete != ERROR_FILE_NOT_FOUND) + { + windows_print_error("shell_unregister", "Error deleting registry key", result_delete); + if(result_delete == ERROR_SUCCESS) + *updated = true; + return false; + } + + return true; +} + void shell_update() { SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); diff --git a/src/base/system.h b/src/base/system.h index 27195e22e..17916a3de 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -2603,6 +2603,22 @@ bool shell_register_protocol(const char *protocol_name, const char *executable, */ bool shell_register_extension(const char *extension, const char *description, const char *executable_name, const char *executable, bool *updated); +/** + * Unregisters a protocol or file extension handler. + * + * @ingroup Shell + * + * @param shell_class The shell class to delete. + * For protocols this is the name of the protocol. + * For file extensions this is the program ID associated with the file extension. + * @param updated Pointer to a variable that will be set to true, iff the shell needs to be updated. + * + * @return true on success, false on failure. + * + * @remark The caller must later call shell_update, iff the shell needs to be updated. + */ +bool shell_unregister(const char *shell_class, bool *updated); + /** * Notifies the system that a protocol or file extension has been changed and the shell needs to be updated. *