atom_api_shell.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 "atom/common/native_mate_converters/callback.h"
  6. #include "atom/common/native_mate_converters/file_path_converter.h"
  7. #include "atom/common/native_mate_converters/gurl_converter.h"
  8. #include "atom/common/native_mate_converters/string16_converter.h"
  9. #include "atom/common/node_includes.h"
  10. #include "atom/common/platform_util.h"
  11. #include "native_mate/dictionary.h"
  12. #if defined(OS_WIN)
  13. #include "base/win/scoped_com_initializer.h"
  14. #include "base/win/shortcut.h"
  15. namespace mate {
  16. template <>
  17. struct Converter<base::win::ShortcutOperation> {
  18. static bool FromV8(v8::Isolate* isolate,
  19. v8::Handle<v8::Value> val,
  20. base::win::ShortcutOperation* out) {
  21. std::string operation;
  22. if (!ConvertFromV8(isolate, val, &operation))
  23. return false;
  24. if (operation.empty() || operation == "create")
  25. *out = base::win::SHORTCUT_CREATE_ALWAYS;
  26. else if (operation == "update")
  27. *out = base::win::SHORTCUT_UPDATE_EXISTING;
  28. else if (operation == "replace")
  29. *out = base::win::SHORTCUT_REPLACE_EXISTING;
  30. else
  31. return false;
  32. return true;
  33. }
  34. };
  35. } // namespace mate
  36. #endif
  37. namespace {
  38. void OnOpenExternalFinished(
  39. v8::Isolate* isolate,
  40. const base::Callback<void(v8::Local<v8::Value>)>& callback,
  41. const std::string& error) {
  42. if (error.empty())
  43. callback.Run(v8::Null(isolate));
  44. else
  45. callback.Run(v8::String::NewFromUtf8(isolate, error.c_str()));
  46. }
  47. bool OpenExternal(
  48. #if defined(OS_WIN)
  49. const base::string16& url,
  50. #else
  51. const GURL& url,
  52. #endif
  53. mate::Arguments* args) {
  54. platform_util::OpenExternalOptions options;
  55. if (args->Length() >= 2) {
  56. mate::Dictionary obj;
  57. if (args->GetNext(&obj)) {
  58. obj.Get("activate", &options.activate);
  59. obj.Get("workingDirectory", &options.working_dir);
  60. }
  61. }
  62. if (args->Length() >= 3) {
  63. base::Callback<void(v8::Local<v8::Value>)> callback;
  64. if (args->GetNext(&callback)) {
  65. platform_util::OpenExternal(
  66. url, options,
  67. base::Bind(&OnOpenExternalFinished, args->isolate(), callback));
  68. return true;
  69. }
  70. }
  71. return platform_util::OpenExternal(url, options);
  72. }
  73. #if defined(OS_WIN)
  74. bool WriteShortcutLink(const base::FilePath& shortcut_path,
  75. mate::Arguments* args) {
  76. base::win::ShortcutOperation operation = base::win::SHORTCUT_CREATE_ALWAYS;
  77. args->GetNext(&operation);
  78. mate::Dictionary options = mate::Dictionary::CreateEmpty(args->isolate());
  79. if (!args->GetNext(&options)) {
  80. args->ThrowError();
  81. return false;
  82. }
  83. base::win::ShortcutProperties properties;
  84. base::FilePath path;
  85. base::string16 str;
  86. int index;
  87. if (options.Get("target", &path))
  88. properties.set_target(path);
  89. if (options.Get("cwd", &path))
  90. properties.set_working_dir(path);
  91. if (options.Get("args", &str))
  92. properties.set_arguments(str);
  93. if (options.Get("description", &str))
  94. properties.set_description(str);
  95. if (options.Get("icon", &path) && options.Get("iconIndex", &index))
  96. properties.set_icon(path, index);
  97. if (options.Get("appUserModelId", &str))
  98. properties.set_app_id(str);
  99. base::win::ScopedCOMInitializer com_initializer;
  100. return base::win::CreateOrUpdateShortcutLink(shortcut_path, properties,
  101. operation);
  102. }
  103. v8::Local<v8::Value> ReadShortcutLink(mate::Arguments* args,
  104. const base::FilePath& path) {
  105. using base::win::ShortcutProperties;
  106. mate::Dictionary options = mate::Dictionary::CreateEmpty(args->isolate());
  107. base::win::ScopedCOMInitializer com_initializer;
  108. base::win::ShortcutProperties properties;
  109. if (!base::win::ResolveShortcutProperties(
  110. path, ShortcutProperties::PROPERTIES_ALL, &properties)) {
  111. args->ThrowError("Failed to read shortcut link");
  112. return v8::Null(args->isolate());
  113. }
  114. options.Set("target", properties.target);
  115. options.Set("cwd", properties.working_dir);
  116. options.Set("args", properties.arguments);
  117. options.Set("description", properties.description);
  118. options.Set("icon", properties.icon);
  119. options.Set("iconIndex", properties.icon_index);
  120. options.Set("appUserModelId", properties.app_id);
  121. return options.GetHandle();
  122. }
  123. #endif
  124. void Initialize(v8::Local<v8::Object> exports,
  125. v8::Local<v8::Value> unused,
  126. v8::Local<v8::Context> context,
  127. void* priv) {
  128. mate::Dictionary dict(context->GetIsolate(), exports);
  129. dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder);
  130. dict.SetMethod("openItem", &platform_util::OpenItem);
  131. dict.SetMethod("openExternal", &OpenExternal);
  132. dict.SetMethod("moveItemToTrash", &platform_util::MoveItemToTrash);
  133. dict.SetMethod("beep", &platform_util::Beep);
  134. #if defined(OS_WIN)
  135. dict.SetMethod("writeShortcutLink", &WriteShortcutLink);
  136. dict.SetMethod("readShortcutLink", &ReadShortcutLink);
  137. #endif
  138. }
  139. } // namespace
  140. NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_shell, Initialize)