:zap: Add API: RemoveAsDefaultProtocolHandler
authorFelix Rieseberg <felix@felixrieseberg.com>
Thu, 24 Mar 2016 17:55:09 +0000 (10:55 -0700)
committerFelix Rieseberg <felix@felixrieseberg.com>
Mon, 28 Mar 2016 22:31:01 +0000 (15:31 -0700)
atom/browser/api/atom_api_app.cc
atom/browser/browser.h
atom/browser/browser_linux.cc
atom/browser/browser_mac.mm
atom/browser/browser_win.cc
docs/api/app.md

index 00edcf7..ad5b721 100644 (file)
@@ -372,6 +372,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
                  base::Bind(&Browser::SetAppUserModelID, browser))
       .SetMethod("setAsDefaultProtocolClient",
                  base::Bind(&Browser::SetAsDefaultProtocolClient, browser))
+      .SetMethod("removeAsDefaultProtocolClient",
+                 base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser))
 #if defined(OS_MACOSX)
       .SetMethod("hide", base::Bind(&Browser::Hide, browser))
       .SetMethod("show", base::Bind(&Browser::Show, browser))
index 38899c1..634e14e 100644 (file)
@@ -76,6 +76,9 @@ class Browser : public WindowListObserver {
   // Set the application user model ID.
   void SetAppUserModelID(const base::string16& name);
 
+  // Remove the default protocol handler registry key
+  bool RemoveAsDefaultProtocolClient(const std::string& protocol);
+
   // Set as default handler for a protocol.
   bool SetAsDefaultProtocolClient(const std::string& protocol);
 
index 586ec71..6c7d4ab 100644 (file)
@@ -34,6 +34,10 @@ void Browser::ClearRecentDocuments() {
 void Browser::SetAppUserModelID(const base::string16& name) {
 }
 
+bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
+  return false;
+}
+
 bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
   return false;
 }
index c61a9bd..0294894 100644 (file)
@@ -46,6 +46,10 @@ void Browser::ClearRecentDocuments() {
   [[NSDocumentController sharedDocumentController] clearRecentDocuments:nil];
 }
 
+bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
+  return false;
+}
+
 bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
   if (protocol.empty())
     return false;
index 0b9fe54..9531406 100644 (file)
@@ -126,6 +126,53 @@ void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
   destinations->CommitList();
 }
 
+bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
+  if (protocol.empty())
+    return false;
+
+  base::FilePath path;
+  if (!PathService::Get(base::FILE_EXE, &path)) {
+    LOG(ERROR) << "Error getting app exe path";
+    return false;
+  }
+
+  // Main Registry Key
+  HKEY root = HKEY_CURRENT_USER;
+  std::string keyPathStr = "Software\\Classes\\" + protocol;
+  std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());
+
+  // Command Key
+  std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
+  std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());
+
+  base::win::RegKey key;
+  base::win::RegKey commandKey;
+  if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS)))
+    // Key doesn't even exist, we can confirm that it is not set
+    return true;
+
+  if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS)))
+    // Key doesn't even exist, we can confirm that it is not set
+    return true;
+
+  std::wstring keyVal;
+  if (FAILED(commandKey.ReadValue(L"", &keyVal)))
+    // Default value not set, we can confirm that it is not set
+    return true;
+
+  std::wstring exePath(path.value());
+  std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
+  if (keyVal == exe) {
+    // Let's kill the key
+    if (FAILED(key.DeleteKey(L"shell")))
+      return false;
+
+    return true;
+  } else {
+    return true;
+  }
+}
+
 bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
   // HKEY_CLASSES_ROOT
   //    $PROTOCOL
@@ -175,7 +222,6 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
   if (FAILED(commandKey.WriteValue(L"", exe.c_str())))
     return false;
 
-  VLOG(1) << "Chrome registered as default handler for " << protocol << ".";
   return true;
 }
 
index e9bd106..94fb283 100644 (file)
@@ -367,6 +367,16 @@ Please refer to [Apple's documentation][CFBundleURLTypes] for details.
 
 The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally.
 
+### `app.removeAsDefaultProtocolClient(protocol)` _Windows_
+
+ * `protocol` String - The name of your protocol, without `://`.
+   
+This method checks if the current executable as the default handler for a protocol
+(aka URI scheme). If so, it will remove the app as the default handler.
+**Note:** On OS X, removing the app will automatically remove the app as the
+default protocol handler.
+
 ### `app.setUserTasks(tasks)` _Windows_
 
 * `tasks` Array - Array of `Task` objects