Skip to content

Commit

Permalink
Moved OS specific code from ActionOpen to WindowsProcessLauncherServi…
Browse files Browse the repository at this point in the history
…ce implementation.
  • Loading branch information
end2endzone committed Sep 22, 2024
1 parent 45b1704 commit 8117efe
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 38 deletions.
46 changes: 11 additions & 35 deletions src/core/ActionOpen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,9 @@
#include "ObjectFactory.h"
#include "LoggerHelper.h"

//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Windows.h>
#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";
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
41 changes: 40 additions & 1 deletion src/core/IProcessLauncherService.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,46 @@ namespace shellanything
IProcessLauncherService& operator=(const IProcessLauncherService&);
public:

virtual bool IsFooBar() const = 0;
/// <summary>
/// The value to use to represent an invalid process id (pID).
/// </summary>
const uint32_t INVALID_PROCESS_ID = 0;

struct ProcessLaunchResult
{
uint32_t pId; // PROCESS ID
};

/// <summary>
/// Open a document with the default system application.
/// </summary>
/// <param name="path">The path to the document to open.</param>
/// <param name="result">The optional result of the process launch.</param>
/// <returns>Returns true if the document was opened with the system's default application. Returns false otherwise.</returns>
virtual bool OpenDocument(const std::string& path, ProcessLaunchResult * result = NULL) const = 0;

/// <summary>
/// Open a directory with the system file explorer.
/// </summary>
/// <param name="path">The path to the directory to open.</param>
/// <param name="result">The optional result of the process launch.</param>
/// <returns>Returns true if the given directory was opened with the system's default application. Returns false otherwise.</returns>
virtual bool OpenPath(const std::string& path, ProcessLaunchResult* result = NULL) const = 0;

/// <summary>
/// Check if the given URL is valid.
/// </summary>
/// <param name="value">The url link to validate.</param>
/// <returns>Returns true if the given url is valid. Returns false otherwise.</returns>
virtual bool IsValidUrl(const std::string& value) const = 0;

/// <summary>
/// Open an url with the system default browser.
/// </summary>
/// <param name="path">The url path to open.</param>
/// <param name="result">The optional result of the process launch.</param>
/// <returns>Returns true if the given url was opened with the system's default application. Returns false otherwise.</returns>
virtual bool OpenUrl(const std::string& path, ProcessLaunchResult* result = NULL) const = 0;

};

Expand Down
65 changes: 64 additions & 1 deletion src/windows/WindowsProcessLauncherService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Windows.h>
#include "rapidassist/undef_windows_macros.h"
#include <shellapi.h>

#include <urlmon.h>
#pragma comment(lib, "Urlmon.lib") //for IsValidURL()

namespace shellanything
{
Expand All @@ -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
31 changes: 30 additions & 1 deletion src/windows/WindowsProcessLauncherService.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,36 @@ namespace shellanything
WindowsProcessLauncherService& operator=(const WindowsProcessLauncherService&);
public:

virtual bool IsFooBar() const;
/// <summary>
/// Open a document with the default system application.
/// </summary>
/// <param name="path">The path to the document to open.</param>
/// <param name="result">The optional result of the process launch.</param>
/// <returns>Returns true if the document was opened with the system's default application. Returns false otherwise.</returns>
virtual bool OpenDocument(const std::string& path, ProcessLaunchResult* result = NULL) const;

/// <summary>
/// Open a directory with the system file explorer.
/// </summary>
/// <param name="path">The path to the directory to open.</param>
/// <param name="result">The optional result of the process launch.</param>
/// <returns>Returns true if the given directory was opened with the system's default application. Returns false otherwise.</returns>
virtual bool OpenPath(const std::string& path, ProcessLaunchResult* result = NULL) const;

/// <summary>
/// Check if the given URL is valid.
/// </summary>
/// <param name="value">The url link to validate.</param>
/// <returns>Returns true if the given url is valid. Returns false otherwise.</returns>
virtual bool IsValidUrl(const std::string& value) const;

/// <summary>
/// Open an url with the system default browser.
/// </summary>
/// <param name="path">The url path to open.</param>
/// <param name="result">The optional result of the process launch.</param>
/// <returns>Returns true if the given url was opened with the system's default application. Returns false otherwise.</returns>
virtual bool OpenUrl(const std::string& path, ProcessLaunchResult* result = NULL) const;

};

Expand Down

0 comments on commit 8117efe

Please sign in to comment.