atom_api_shell.cc 4.9 KB

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