diff --git a/src/core/ActionOpen.cpp b/src/core/ActionOpen.cpp index 29bd18a..c42498d 100644 --- a/src/core/ActionOpen.cpp +++ b/src/core/ActionOpen.cpp @@ -30,15 +30,9 @@ #include "ObjectFactory.h" #include "LoggerHelper.h" - //#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#include -#include "rapidassist/undef_windows_macros.h" - #include "tinyxml2.h" using namespace tinyxml2; -#pragma comment(lib, "Urlmon.lib") //for IsValidURL() - namespace shellanything { const std::string ActionOpen::XML_ELEMENT_NAME = "open"; @@ -106,40 +100,23 @@ namespace shellanything { } - bool OpenPathGeneric(const std::string& path) - { - std::wstring pathW = ra::unicode::Utf8ToUnicode(path); - - SHELLEXECUTEINFOW info = { 0 }; - - info.cbSize = sizeof(SHELLEXECUTEINFOW); - - info.fMask |= SEE_MASK_NOCLOSEPROCESS; - info.fMask |= SEE_MASK_NOASYNC; - info.fMask |= SEE_MASK_FLAG_DDEWAIT; - - info.hwnd = HWND_DESKTOP; - info.nShow = SW_SHOWDEFAULT; - info.lpVerb = L"open"; - info.lpFile = pathW.c_str(); - info.lpParameters = NULL; // arguments - info.lpDirectory = NULL; // Default directory - - BOOL success = ShellExecuteExW(&info); - return (success == TRUE); - } - bool ActionOpen::Execute(const SelectionContext& context) const { PropertyManager& pmgr = PropertyManager::GetInstance(); std::string path = pmgr.Expand(mPath); + IProcessLauncherService* process_launcher_service = App::GetInstance().GetProcessLauncherService(); + if (process_launcher_service == NULL) + { + SA_LOG(ERROR) << "No Process Launcher service configured for creating process."; + return false; + } + //is path a file? if (ra::filesystem::FileExistsUtf8(path.c_str())) { SA_LOG(INFO) << "Open file '" << path << "'."; - uint32_t pId = ra::process::OpenDocumentUtf8(path); - bool success = (pId != ra::process::INVALID_PROCESS_ID); + bool success = process_launcher_service->OpenDocument(path); if (!success) SA_LOG(ERROR) << "Failed opening file '" << path << "'."; return success; @@ -149,18 +126,17 @@ namespace shellanything if (ra::filesystem::DirectoryExistsUtf8(path.c_str())) { SA_LOG(INFO) << "Open directory '" << path << "'."; - bool success = OpenPathGeneric(path); + bool success = process_launcher_service->OpenPath(path); if (!success) SA_LOG(ERROR) << "Failed opening directory '" << path << "'."; return success; } //is path a valid url? - std::wstring wide_path = ra::unicode::Utf8ToUnicode(path); - if (IsValidURL(NULL, wide_path.c_str(), 0) == S_OK) + if (process_launcher_service->IsValidUrl(path)) { SA_LOG(INFO) << "Open url '" << path << "'."; - bool success = OpenPathGeneric(path); + bool success = process_launcher_service->OpenUrl(path); if (!success) SA_LOG(ERROR) << "Failed opening URL '" << path << "'."; return success; diff --git a/src/core/IProcessLauncherService.h b/src/core/IProcessLauncherService.h index d20dd52..ed83166 100644 --- a/src/core/IProcessLauncherService.h +++ b/src/core/IProcessLauncherService.h @@ -49,7 +49,46 @@ namespace shellanything IProcessLauncherService& operator=(const IProcessLauncherService&); public: - virtual bool IsFooBar() const = 0; + /// + /// The value to use to represent an invalid process id (pID). + /// + const uint32_t INVALID_PROCESS_ID = 0; + + struct ProcessLaunchResult + { + uint32_t pId; // PROCESS ID + }; + + /// + /// Open a document with the default system application. + /// + /// The path to the document to open. + /// The optional result of the process launch. + /// Returns true if the document was opened with the system's default application. Returns false otherwise. + virtual bool OpenDocument(const std::string& path, ProcessLaunchResult * result = NULL) const = 0; + + /// + /// Open a directory with the system file explorer. + /// + /// The path to the directory to open. + /// The optional result of the process launch. + /// Returns true if the given directory was opened with the system's default application. Returns false otherwise. + virtual bool OpenPath(const std::string& path, ProcessLaunchResult* result = NULL) const = 0; + + /// + /// Check if the given URL is valid. + /// + /// The url link to validate. + /// Returns true if the given url is valid. Returns false otherwise. + virtual bool IsValidUrl(const std::string& value) const = 0; + + /// + /// Open an url with the system default browser. + /// + /// The url path to open. + /// The optional result of the process launch. + /// Returns true if the given url was opened with the system's default application. Returns false otherwise. + virtual bool OpenUrl(const std::string& path, ProcessLaunchResult* result = NULL) const = 0; }; diff --git a/src/windows/WindowsProcessLauncherService.cpp b/src/windows/WindowsProcessLauncherService.cpp index 5d29e93..122b1ae 100644 --- a/src/windows/WindowsProcessLauncherService.cpp +++ b/src/windows/WindowsProcessLauncherService.cpp @@ -23,6 +23,16 @@ *********************************************************************************/ #include "WindowsProcessLauncherService.h" +#include "rapidassist/process_utf8.h" +#include "rapidassist/unicode.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +#include "rapidassist/undef_windows_macros.h" +#include + +#include +#pragma comment(lib, "Urlmon.lib") //for IsValidURL() namespace shellanything { @@ -34,9 +44,62 @@ namespace shellanything { } - bool WindowsProcessLauncherService::IsFooBar() const + bool WindowsProcessLauncherService::OpenDocument(const std::string& path, ProcessLaunchResult* result) const + { + uint32_t pId = ra::process::OpenDocumentUtf8(path); + bool success = (pId != ra::process::INVALID_PROCESS_ID); + + if (result) + { + result->pId = pId; + } + + return success; + } + + bool WindowsProcessLauncherService::OpenPath(const std::string& path, ProcessLaunchResult* result) const { + std::wstring pathW = ra::unicode::Utf8ToUnicode(path); + + SHELLEXECUTEINFOW info = { 0 }; + + info.cbSize = sizeof(SHELLEXECUTEINFOW); + + info.fMask |= SEE_MASK_NOCLOSEPROCESS; + info.fMask |= SEE_MASK_NOASYNC; + info.fMask |= SEE_MASK_FLAG_DDEWAIT; + + info.hwnd = HWND_DESKTOP; + info.nShow = SW_SHOWDEFAULT; + info.lpVerb = L"open"; + info.lpFile = pathW.c_str(); + info.lpParameters = NULL; // arguments + info.lpDirectory = NULL; // Default directory + + bool success = (ShellExecuteExW(&info) == TRUE); + + if (result) + { + DWORD dwPid = GetProcessId(info.hProcess); + result->pId = dwPid; + } + return success; + } + + bool WindowsProcessLauncherService::IsValidUrl(const std::string& value) const + { + std::wstring valueW = ra::unicode::Utf8ToUnicode(value); + if (::IsValidURL(NULL, valueW.c_str(), 0) == S_OK) + { + return true; + } return false; } + bool WindowsProcessLauncherService::OpenUrl(const std::string& path, ProcessLaunchResult* result) const + { + bool success = OpenPath(path, result); + return success; + } + } //namespace shellanything diff --git a/src/windows/WindowsProcessLauncherService.h b/src/windows/WindowsProcessLauncherService.h index c0bf238..d3ee529 100644 --- a/src/windows/WindowsProcessLauncherService.h +++ b/src/windows/WindowsProcessLauncherService.h @@ -45,7 +45,36 @@ namespace shellanything WindowsProcessLauncherService& operator=(const WindowsProcessLauncherService&); public: - virtual bool IsFooBar() const; + /// + /// Open a document with the default system application. + /// + /// The path to the document to open. + /// The optional result of the process launch. + /// Returns true if the document was opened with the system's default application. Returns false otherwise. + virtual bool OpenDocument(const std::string& path, ProcessLaunchResult* result = NULL) const; + + /// + /// Open a directory with the system file explorer. + /// + /// The path to the directory to open. + /// The optional result of the process launch. + /// Returns true if the given directory was opened with the system's default application. Returns false otherwise. + virtual bool OpenPath(const std::string& path, ProcessLaunchResult* result = NULL) const; + + /// + /// Check if the given URL is valid. + /// + /// The url link to validate. + /// Returns true if the given url is valid. Returns false otherwise. + virtual bool IsValidUrl(const std::string& value) const; + + /// + /// Open an url with the system default browser. + /// + /// The url path to open. + /// The optional result of the process launch. + /// Returns true if the given url was opened with the system's default application. Returns false otherwise. + virtual bool OpenUrl(const std::string& path, ProcessLaunchResult* result = NULL) const; };