electron_api_shell.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright (c) 2013 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include <string>
  5. #include "shell/common/gin_converters/callback_converter.h"
  6. #include "shell/common/gin_converters/file_path_converter.h"
  7. #include "shell/common/gin_converters/gurl_converter.h"
  8. #include "shell/common/gin_helper/dictionary.h"
  9. #include "shell/common/gin_helper/error_thrower.h"
  10. #include "shell/common/gin_helper/promise.h"
  11. #include "shell/common/node_includes.h"
  12. #include "shell/common/platform_util.h"
  13. #if defined(OS_WIN)
  14. #include "base/win/scoped_com_initializer.h"
  15. #include "base/win/shortcut.h"
  16. namespace gin {
  17. template <>
  18. struct Converter<base::win::ShortcutOperation> {
  19. static bool FromV8(v8::Isolate* isolate,
  20. v8::Handle<v8::Value> val,
  21. base::win::ShortcutOperation* out) {
  22. std::string operation;
  23. if (!ConvertFromV8(isolate, val, &operation))
  24. return false;
  25. if (operation.empty() || operation == "create")
  26. *out = base::win::SHORTCUT_CREATE_ALWAYS;
  27. else if (operation == "update")
  28. *out = base::win::SHORTCUT_UPDATE_EXISTING;
  29. else if (operation == "replace")
  30. *out = base::win::SHORTCUT_REPLACE_EXISTING;
  31. else
  32. return false;
  33. return true;
  34. }
  35. };
  36. } // namespace gin
  37. #endif
  38. namespace {
  39. void OnOpenFinished(gin_helper::Promise<void> promise,
  40. const std::string& error) {
  41. if (error.empty())
  42. promise.Resolve();
  43. else
  44. promise.RejectWithErrorMessage(error.c_str());
  45. }
  46. v8::Local<v8::Promise> OpenExternal(const GURL& url, gin::Arguments* args) {
  47. gin_helper::Promise<void> promise(args->isolate());
  48. v8::Local<v8::Promise> handle = promise.GetHandle();
  49. platform_util::OpenExternalOptions options;
  50. if (args->Length() >= 2) {
  51. gin::Dictionary obj(nullptr);
  52. if (args->GetNext(&obj)) {
  53. obj.Get("activate", &options.activate);
  54. obj.Get("workingDirectory", &options.working_dir);
  55. }
  56. }
  57. platform_util::OpenExternal(
  58. url, options, base::BindOnce(&OnOpenFinished, std::move(promise)));
  59. return handle;
  60. }
  61. v8::Local<v8::Promise> OpenPath(v8::Isolate* isolate,
  62. const base::FilePath& full_path) {
  63. gin_helper::Promise<const std::string&> promise(isolate);
  64. v8::Local<v8::Promise> handle = promise.GetHandle();
  65. platform_util::OpenPath(
  66. full_path,
  67. base::BindOnce(
  68. [](gin_helper::Promise<const std::string&> promise,
  69. const std::string& err_msg) { promise.Resolve(err_msg); },
  70. std::move(promise)));
  71. return handle;
  72. }
  73. bool MoveItemToTrash(gin::Arguments* args) {
  74. base::FilePath full_path;
  75. args->GetNext(&full_path);
  76. bool delete_on_fail = false;
  77. args->GetNext(&delete_on_fail);
  78. return platform_util::MoveItemToTrash(full_path, delete_on_fail);
  79. }
  80. #if defined(OS_WIN)
  81. bool WriteShortcutLink(const base::FilePath& shortcut_path,
  82. gin_helper::Arguments* args) {
  83. base::win::ShortcutOperation operation = base::win::SHORTCUT_CREATE_ALWAYS;
  84. args->GetNext(&operation);
  85. gin::Dictionary options = gin::Dictionary::CreateEmpty(args->isolate());
  86. if (!args->GetNext(&options)) {
  87. args->ThrowError();
  88. return false;
  89. }
  90. base::win::ShortcutProperties properties;
  91. base::FilePath path;
  92. base::string16 str;
  93. int index;
  94. if (options.Get("target", &path))
  95. properties.set_target(path);
  96. if (options.Get("cwd", &path))
  97. properties.set_working_dir(path);
  98. if (options.Get("args", &str))
  99. properties.set_arguments(str);
  100. if (options.Get("description", &str))
  101. properties.set_description(str);
  102. if (options.Get("icon", &path) && options.Get("iconIndex", &index))
  103. properties.set_icon(path, index);
  104. if (options.Get("appUserModelId", &str))
  105. properties.set_app_id(str);
  106. base::win::ScopedCOMInitializer com_initializer;
  107. return base::win::CreateOrUpdateShortcutLink(shortcut_path, properties,
  108. operation);
  109. }
  110. v8::Local<v8::Value> ReadShortcutLink(gin_helper::ErrorThrower thrower,
  111. const base::FilePath& path) {
  112. using base::win::ShortcutProperties;
  113. gin::Dictionary options = gin::Dictionary::CreateEmpty(thrower.isolate());
  114. base::win::ScopedCOMInitializer com_initializer;
  115. base::win::ShortcutProperties properties;
  116. if (!base::win::ResolveShortcutProperties(
  117. path, ShortcutProperties::PROPERTIES_ALL, &properties)) {
  118. thrower.ThrowError("Failed to read shortcut link");
  119. return v8::Null(thrower.isolate());
  120. }
  121. options.Set("target", properties.target);
  122. options.Set("cwd", properties.working_dir);
  123. options.Set("args", properties.arguments);
  124. options.Set("description", properties.description);
  125. options.Set("icon", properties.icon);
  126. options.Set("iconIndex", properties.icon_index);
  127. options.Set("appUserModelId", properties.app_id);
  128. return gin::ConvertToV8(thrower.isolate(), options);
  129. }
  130. #endif
  131. void Initialize(v8::Local<v8::Object> exports,
  132. v8::Local<v8::Value> unused,
  133. v8::Local<v8::Context> context,
  134. void* priv) {
  135. gin_helper::Dictionary dict(context->GetIsolate(), exports);
  136. dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder);
  137. dict.SetMethod("openPath", &OpenPath);
  138. dict.SetMethod("openExternal", &OpenExternal);
  139. dict.SetMethod("moveItemToTrash", &MoveItemToTrash);
  140. dict.SetMethod("beep", &platform_util::Beep);
  141. #if defined(OS_WIN)
  142. dict.SetMethod("writeShortcutLink", &WriteShortcutLink);
  143. dict.SetMethod("readShortcutLink", &ReadShortcutLink);
  144. #endif
  145. }
  146. } // namespace
  147. NODE_LINKED_MODULE_CONTEXT_AWARE(electron_common_shell, Initialize)