From e5daf63b0ee60098d43de281260743b41985fda4 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Tue, 16 Aug 2016 15:35:20 +1000 Subject: [PATCH] Allow client to specify EXE file and args to set as default handler * Optional path param to setAsDefaultProtocolClient * Optional args param to setAsDefaultProtocolClient --- atom/browser/browser.h | 6 +-- atom/browser/browser_linux.cc | 6 +-- atom/browser/browser_mac.mm | 6 +-- atom/browser/browser_win.cc | 69 +++++++++++++++++++++++------------ 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/atom/browser/browser.h b/atom/browser/browser.h index a3494fb8a08a..bf12c1e40bd4 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -76,13 +76,13 @@ class Browser : public WindowListObserver { void SetAppUserModelID(const base::string16& name); // Remove the default protocol handler registry key - bool RemoveAsDefaultProtocolClient(const std::string& protocol); + bool RemoveAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args); // Set as default handler for a protocol. - bool SetAsDefaultProtocolClient(const std::string& protocol); + bool SetAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args); // Query the current state of default handler for a protocol. - bool IsDefaultProtocolClient(const std::string& protocol); + bool IsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args); // Set/Get the badge count. bool SetBadgeCount(int count); diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index 6aff6027266f..9bd2288d85df 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -35,15 +35,15 @@ void Browser::ClearRecentDocuments() { void Browser::SetAppUserModelID(const base::string16& name) { } -bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { +bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { return false; } -bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { +bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { return false; } -bool Browser::IsDefaultProtocolClient(const std::string& protocol) { +bool Browser::IsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { return false; } diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 2cfb4ca2cdf6..bebee8945fd4 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -46,7 +46,7 @@ void Browser::ClearRecentDocuments() { [[NSDocumentController sharedDocumentController] clearRecentDocuments:nil]; } -bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { +bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { NSString* identifier = [base::mac::MainBundle() bundleIdentifier]; if (!identifier) return false; @@ -74,7 +74,7 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { return return_code == noErr; } -bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { +bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { if (protocol.empty()) return false; @@ -89,7 +89,7 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { return return_code == noErr; } -bool Browser::IsDefaultProtocolClient(const std::string& protocol) { +bool Browser::IsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { if (protocol.empty()) return false; diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index 8f4ad27ff043..2dcf0f4fd152 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -125,16 +125,47 @@ bool Browser::SetUserTasks(const std::vector& tasks) { return SUCCEEDED(destinations->CommitList()); } -bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { - if (protocol.empty()) - return false; +std::wstring protocolLaunchPath(std::string protocol, mate::Arguments* args) { + // Read in optional exe path arg + std::wstring exePath; + std::string rawExePath; base::FilePath path; - if (!PathService::Get(base::FILE_EXE, &path)) { - LOG(ERROR) << "Error getting app exe path"; - return false; + + if (!args->GetNext(&rawExePath)) { + if (!PathService::Get(base::FILE_EXE, &path)) { + LOG(ERROR) << "Error getting app exe path"; + return L""; + } + // Executable Path + exePath = path.value(); + } else { + exePath.assign(rawExePath.begin(), rawExePath.end()); } + // Read in optional args arg + std::vector launchArgs; + args->GetNext(&launchArgs); + + std::wstring exe = L"\"" + exePath + L"\" "; + + // Parse launch args into a string of space spearated args + if (launchArgs.size() != 0) { + std::string launchArgString = ""; + for (std::string launchArg : launchArgs) { + launchArgString = launchArgString + launchArg + " "; + } + std::wstring wLaunchArgString; + wLaunchArgString.assign(launchArgString.begin(), launchArgString.end()); + exe = exe + L"\"" + wLaunchArgString + L"\""; + } + return exe + L"\"%1\""; +} + +bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { + if (protocol.empty()) + return false; + // Main Registry Key HKEY root = HKEY_CURRENT_USER; std::string keyPathStr = "Software\\Classes\\" + protocol; @@ -159,8 +190,9 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { // 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\""; + std::wstring exe = protocolLaunchPath(protocol, args); + if (exe == L"") + return false; if (keyVal == exe) { // Let's kill the key if (FAILED(key.DeleteKey(L"shell"))) @@ -172,7 +204,7 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { } } -bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { +bool Browser::SetAsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { // HKEY_CLASSES_ROOT // $PROTOCOL // (Default) = "URL:$NAME" @@ -190,9 +222,8 @@ bool Browser::SetAsDefaultProtocolClient(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"; + std::wstring exe = protocolLaunchPath(protocol, args); + if (exe == L"") { return false; } @@ -207,10 +238,6 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { std::string cmdPathStr = keyPathStr + "\\shell\\open\\command"; std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end()); - // Executable Path - std::wstring exePath(path.value()); - std::wstring exe = L"\"" + exePath + L"\" \"%1\""; - // Write information to registry base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS); if (FAILED(key.WriteValue(L"URL Protocol", L"")) || @@ -224,15 +251,13 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { return true; } -bool Browser::IsDefaultProtocolClient(const std::string& protocol) { +bool Browser::IsDefaultProtocolClient(const std::string& protocol, mate::Arguments* args) { if (protocol.empty()) return false; - base::FilePath path; - if (!PathService::Get(base::FILE_EXE, &path)) { - LOG(ERROR) << "Error getting app exe path"; + std::wstring exe = protocolLaunchPath(protocol, args); + if (exe == L"") return false; - } // Main Registry Key HKEY root = HKEY_CURRENT_USER; @@ -258,8 +283,6 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) { // Default value not set, we can confirm that it is not set return false; - std::wstring exePath(path.value()); - std::wstring exe = L"\"" + exePath + L"\" \"%1\""; if (keyVal == exe) { // Default value is the same as current file path return true;