Merge pull request #6858 from electron/default-protocol-launch-args

Allow settings of launch args when using defaultProtocol
This commit is contained in:
Cheng Zhao 2016-08-22 09:32:54 +09:00 committed by GitHub
commit 8b9fd8a76e
5 changed files with 76 additions and 35 deletions

View file

@ -76,13 +76,16 @@ class Browser : public WindowListObserver {
void SetAppUserModelID(const base::string16& name); void SetAppUserModelID(const base::string16& name);
// Remove the default protocol handler registry key // 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. // 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. // 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. // Set/Get the badge count.
bool SetBadgeCount(int count); bool SetBadgeCount(int count);

View file

@ -35,15 +35,18 @@ void Browser::ClearRecentDocuments() {
void Browser::SetAppUserModelID(const base::string16& name) { 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; return false;
} }
bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { bool Browser::SetAsDefaultProtocolClient(const std::string& protocol,
mate::Arguments* args) {
return false; return false;
} }
bool Browser::IsDefaultProtocolClient(const std::string& protocol) { bool Browser::IsDefaultProtocolClient(const std::string& protocol,
mate::Arguments* args) {
return false; return false;
} }

View file

@ -46,12 +46,13 @@ void Browser::ClearRecentDocuments() {
[[NSDocumentController sharedDocumentController] clearRecentDocuments:nil]; [[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]; NSString* identifier = [base::mac::MainBundle() bundleIdentifier];
if (!identifier) if (!identifier)
return false; return false;
if (!Browser::IsDefaultProtocolClient(protocol)) if (!Browser::IsDefaultProtocolClient(protocol, args))
return false; return false;
NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()]; NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()];
@ -74,7 +75,8 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
return return_code == noErr; return return_code == noErr;
} }
bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { bool Browser::SetAsDefaultProtocolClient(const std::string& protocol,
mate::Arguments* args) {
if (protocol.empty()) if (protocol.empty())
return false; return false;
@ -89,7 +91,8 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
return return_code == noErr; return return_code == noErr;
} }
bool Browser::IsDefaultProtocolClient(const std::string& protocol) { bool Browser::IsDefaultProtocolClient(const std::string& protocol,
mate::Arguments* args) {
if (protocol.empty()) if (protocol.empty())
return false; return false;

View file

@ -21,6 +21,7 @@
#include "base/win/registry.h" #include "base/win/registry.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "atom/common/atom_version.h" #include "atom/common/atom_version.h"
#include "atom/common/native_mate_converters/string16_converter.h"
namespace atom { namespace atom {
@ -125,15 +126,39 @@ bool Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
return SUCCEEDED(destinations->CommitList()); return SUCCEEDED(destinations->CommitList());
} }
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { bool GetProtocolLaunchPath(mate::Arguments* args, base::string16* exe) {
if (protocol.empty()) // Read in optional exe path arg
return false; base::string16 exePath;
base::FilePath path; base::FilePath path;
if (!args->GetNext(&exePath)) {
if (!PathService::Get(base::FILE_EXE, &path)) { if (!PathService::Get(base::FILE_EXE, &path)) {
LOG(ERROR) << "Error getting app exe path"; LOG(ERROR) << "Error getting app exe path";
return false; return false;
} }
// Executable Path
exePath = path.value();
}
// Read in optional args arg
std::vector<base::string16> launchArgs;
args->GetNext(&launchArgs);
// Parse launch args into a string of space spearated args
base::string16 launchArgString;
if (launchArgs.size() != 0) {
launchArgString = base::JoinString(launchArgs, L" ");
}
*exe = base::StringPrintf(L"\"%s\" %s \"%%1\"",
exePath.c_str(), launchArgString.c_str());
return true;
}
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
mate::Arguments* args) {
if (protocol.empty())
return false;
// Main Registry Key // Main Registry Key
HKEY root = HKEY_CURRENT_USER; HKEY root = HKEY_CURRENT_USER;
@ -159,8 +184,12 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
// Default value not set, we can confirm that it is not set // Default value not set, we can confirm that it is not set
return true; return true;
std::wstring exePath(path.value()); std::wstring exe;
std::wstring exe = L"\"" + exePath + L"\" \"%1\""; if (!GetProtocolLaunchPath(args, &exe)) {
return false;
}
if (exe == L"")
return false;
if (keyVal == exe) { if (keyVal == exe) {
// Let's kill the key // Let's kill the key
if (FAILED(key.DeleteKey(L"shell"))) if (FAILED(key.DeleteKey(L"shell")))
@ -172,7 +201,8 @@ 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 // HKEY_CLASSES_ROOT
// $PROTOCOL // $PROTOCOL
// (Default) = "URL:$NAME" // (Default) = "URL:$NAME"
@ -190,9 +220,8 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
if (protocol.empty()) if (protocol.empty())
return false; return false;
base::FilePath path; std::wstring exe;
if (!PathService::Get(base::FILE_EXE, &path)) { if (!GetProtocolLaunchPath(args, &exe)) {
LOG(ERROR) << "Error getting app exe path";
return false; return false;
} }
@ -207,10 +236,6 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
std::string cmdPathStr = keyPathStr + "\\shell\\open\\command"; std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end()); 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 // Write information to registry
base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS); base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS);
if (FAILED(key.WriteValue(L"URL Protocol", L"")) || if (FAILED(key.WriteValue(L"URL Protocol", L"")) ||
@ -224,13 +249,13 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
return true; return true;
} }
bool Browser::IsDefaultProtocolClient(const std::string& protocol) { bool Browser::IsDefaultProtocolClient(const std::string& protocol,
mate::Arguments* args) {
if (protocol.empty()) if (protocol.empty())
return false; return false;
base::FilePath path; std::wstring exe;
if (!PathService::Get(base::FILE_EXE, &path)) { if (!GetProtocolLaunchPath(args, &exe)) {
LOG(ERROR) << "Error getting app exe path";
return false; return false;
} }
@ -258,8 +283,6 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
// Default value not set, we can confirm that it is not set // Default value not set, we can confirm that it is not set
return false; return false;
std::wstring exePath(path.value());
std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
if (keyVal == exe) { if (keyVal == exe) {
// Default value is the same as current file path // Default value is the same as current file path
return true; return true;

View file

@ -448,11 +448,13 @@ bar, and on macOS you can visit it from dock menu.
Clears the recent documents list. Clears the recent documents list.
### `app.setAsDefaultProtocolClient(protocol)` _macOS_ _Windows_ ### `app.setAsDefaultProtocolClient(protocol[, path, args])` _macOS_ _Windows_
* `protocol` String - The name of your protocol, without `://`. If you want your * `protocol` String - The name of your protocol, without `://`. If you want your
app to handle `electron://` links, call this method with `electron` as the app to handle `electron://` links, call this method with `electron` as the
parameter. parameter.
* `path` String (optional) _Windows_ - Defaults to `process.execPath`
* `args` Array (optional) _Windows_ - Defaults to an empty array
This method sets the current executable as the default handler for a protocol This method sets the current executable as the default handler for a protocol
(aka URI scheme). It allows you to integrate your app deeper into the operating (aka URI scheme). It allows you to integrate your app deeper into the operating
@ -460,6 +462,9 @@ system. Once registered, all links with `your-protocol://` will be opened with
the current executable. The whole link, including protocol, will be passed to the current executable. The whole link, including protocol, will be passed to
your application as a parameter. your application as a parameter.
On Windows you can provide optional parameters path, the path to your executable,
and args, an array of arguments to be passed to your executable when it launches.
Returns `true` when the call succeeded, otherwise returns `false`. Returns `true` when the call succeeded, otherwise returns `false`.
**Note:** On macOS, you can only register protocols that have been added to **Note:** On macOS, you can only register protocols that have been added to
@ -469,18 +474,22 @@ Please refer to [Apple's documentation][CFBundleURLTypes] for details.
The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally. The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally.
### `app.removeAsDefaultProtocolClient(protocol)` _macOS_ _Windows_ ### `app.removeAsDefaultProtocolClient(protocol[, path, args])` _macOS_ _Windows_
* `protocol` String - The name of your protocol, without `://`. * `protocol` String - The name of your protocol, without `://`.
* `path` String (optional) _Windows_ - Defaults to `process.execPath`
* `args` Array (optional) _Windows_ - Defaults to an empty array
This method checks if the current executable as the default handler for a 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. protocol (aka URI scheme). If so, it will remove the app as the default handler.
Returns `true` when the call succeeded, otherwise returns `false`. Returns `true` when the call succeeded, otherwise returns `false`.
### `app.isDefaultProtocolClient(protocol)` _macOS_ _Windows_ ### `app.isDefaultProtocolClient(protocol[, path, args])` _macOS_ _Windows_
* `protocol` String - The name of your protocol, without `://`. * `protocol` String - The name of your protocol, without `://`.
* `path` String (optional) _Windows_ - Defaults to `process.execPath`
* `args` Array (optional) _Windows_ - Defaults to an empty array
This method checks if the current executable is the default handler for a protocol This method checks if the current executable is the default handler for a protocol
(aka URI scheme). If so, it will return true. Otherwise, it will return false. (aka URI scheme). If so, it will return true. Otherwise, it will return false.