Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1004)

Unified Diff: ui/base/win/shell.cc

Issue 352393002: Be explicit about target type in platform_util::OpenItem() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Catch up with changes to JSONStringValueSerializer and address CrOS comment Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/base/win/shell.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/base/win/shell.cc
diff --git a/ui/base/win/shell.cc b/ui/base/win/shell.cc
index 9e47f8c94ac45f50bdeb8e5d0760135c87816198..2a5bd29798da5b9ec878477e1007f07a87eb5c08 100644
--- a/ui/base/win/shell.cc
+++ b/ui/base/win/shell.cc
@@ -11,9 +11,11 @@
#include "base/command_line.h"
#include "base/debug/alias.h"
+#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/native_library.h"
#include "base/strings/string_util.h"
+#include "base/threading/thread_restrictions.h"
#include "base/win/metro.h"
#include "base/win/scoped_comptr.h"
#include "base/win/win_util.h"
@@ -25,15 +27,39 @@ namespace win {
namespace {
-// Show the Windows "Open With" dialog box to ask the user to pick an app to
-// open the file with.
-bool OpenItemWithExternalApp(const base::string16& full_path) {
- SHELLEXECUTEINFO sei = { sizeof(sei) };
- sei.fMask = SEE_MASK_FLAG_DDEWAIT;
+// Default ShellExecuteEx flags used with the "openas" verb.
+//
+// SEE_MASK_NOASYNC is specified so that ShellExecuteEx can be invoked from a
+// thread whose message loop may not wait around long enough for the
+// asynchronous tasks initiated by ShellExecuteEx to complete. Using this flag
+// causes ShellExecuteEx() to block until these tasks complete.
+const DWORD kDefaultOpenAsFlags = SEE_MASK_NOASYNC;
+
+// Default ShellExecuteEx flags used with the "explore", "open" or default verb.
+//
+// See kDefaultOpenFlags for description SEE_MASK_NOASYNC flag.
+// SEE_MASK_FLAG_NO_UI is used to suppress any error message boxes that might be
+// displayed if there is an error in opening the file. Failure in invoking the
+// "open" actions result in invocation of the "saveas" verb, making the error
+// dialog superfluous.
+const DWORD kDefaultOpenFlags = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI;
+
+// Invokes ShellExecuteExW() with the given parameters.
+DWORD InvokeShellExecute(const base::string16 path,
+ const base::string16 working_directory,
+ const base::string16 args,
+ const base::string16 verb,
+ DWORD mask) {
+ base::ThreadRestrictions::AssertIOAllowed();
+ SHELLEXECUTEINFO sei = {sizeof(sei)};
+ sei.fMask = mask;
sei.nShow = SW_SHOWNORMAL;
- sei.lpVerb = L"openas";
- sei.lpFile = full_path.c_str();
- return (TRUE == ::ShellExecuteExW(&sei));
+ sei.lpVerb = (verb.empty() ? nullptr : verb.c_str());
+ sei.lpFile = path.c_str();
+ sei.lpDirectory =
+ (working_directory.empty() ? nullptr : working_directory.c_str());
+ sei.lpParameters = (args.empty() ? nullptr : args.c_str());
+ return ::ShellExecuteExW(&sei) ? ERROR_SUCCESS : ::GetLastError();
}
} // namespace
@@ -42,24 +68,32 @@ bool OpenAnyViaShell(const base::string16& full_path,
const base::string16& directory,
const base::string16& args,
DWORD mask) {
- SHELLEXECUTEINFO sei = { sizeof(sei) };
- sei.fMask = mask;
- sei.nShow = SW_SHOWNORMAL;
- sei.lpFile = full_path.c_str();
- sei.lpDirectory = directory.c_str();
- if (!args.empty())
- sei.lpParameters = args.c_str();
-
- if (::ShellExecuteExW(&sei))
+ DWORD open_result =
+ InvokeShellExecute(full_path, directory, args, base::string16(), mask);
+ if (open_result == ERROR_SUCCESS)
return true;
- if (::GetLastError() == ERROR_NO_ASSOCIATION)
- return OpenItemWithExternalApp(full_path);
+ // Show the Windows "Open With" dialog box to ask the user to pick an app to
+ // open the file with. Note that we are not forwarding |args| for the "openas"
+ // call since the target application is nolonger known at this point.
+ if (open_result == ERROR_NO_ASSOCIATION)
+ return InvokeShellExecute(full_path, directory, base::string16(), L"openas",
+ kDefaultOpenAsFlags) == ERROR_SUCCESS;
return false;
}
-bool OpenItemViaShell(const base::FilePath& full_path) {
+bool OpenFileViaShell(const base::FilePath& full_path) {
return OpenAnyViaShell(full_path.value(), full_path.DirName().value(),
- base::string16(), 0);
+ base::string16(), kDefaultOpenFlags);
+}
+
+bool OpenFolderViaShell(const base::FilePath& full_path) {
+ // The "explore" verb causes the folder at |full_path| to be displayed in a
+ // file browser. This will fail if |full_path| is not a directory. The
+ // resulting error does not cause UI due to the SEE_MASK_FLAG_NO_UI flag in
+ // kDefaultOpenFlags.
+ return InvokeShellExecute(full_path.value(), full_path.value(),
+ base::string16(), L"explore",
+ kDefaultOpenFlags) == ERROR_SUCCESS;
}
bool PreventWindowFromPinning(HWND hwnd) {
« no previous file with comments | « ui/base/win/shell.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698