Skip to content

Commit

Permalink
Merge pull request #74 from end2endzone/feature-issue56
Browse files Browse the repository at this point in the history
Reintegrating issue #56 into master branch.
  • Loading branch information
GasDauMin authored Nov 8, 2020
2 parents c2e7699 + 2a14529 commit 1af4c0c
Show file tree
Hide file tree
Showing 16 changed files with 805 additions and 12 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
# their names here. Please keep the list sorted by first names.

Antoine Beauchamp <end2endzone@gmail.com>
Mindaugas Ribaconka <GasDauMin@gmail.com>
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Changes for 0.5.0
* Fixed issue #52: Define a specific property for use as separator for handling multiple file selection.
* Fixed issue #54: Icon background and dark mode.
* Fixed issue #55: Menu name maximum length limit and escape string.
* Fixed issue #56: Not implemented administrator mode.
* Fixed issue #58: More useful features: class and pattern attributes for validity / visibility.
* Fixed issue #61: Support for WIX installer.
* Fixed issue #66: Github don't identify the repository LICENSE as MIT.
Expand Down
24 changes: 23 additions & 1 deletion UserManual.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![ShellAnything logo](docs/ShellAnything-splashscreen.jpg?raw=true)
![ShellAnything logo](docs/ShellAnything-splashscreen.jpg?raw=true)


# Overview #
Expand Down Expand Up @@ -550,6 +550,28 @@ For example, the following launche `notepad.exe` and open the `License.txt` docu



#### verb attribute: ####

The `verb` attribute defines special directives on how to execute a file or launching the application. For example, the verb `open` or `edit` allows the user to open a document using the associated application. The attribute is optional.

Verbs are specific to a file type but some are supported by multiple types. Commonly available verbs include:
| Verb | Description |
|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| edit | Launches an editor and opens the document for editing. |
| find | Initiates a search starting from the executed directory. |
| open | Launches an application. If this file is not an executable file, its associated application is launched. |
| print | Prints the document file. |
| properties | Displays the object's properties. |
| runas | Launches an application as Administrator. User Account Control (UAC) will prompt the user for consent to run the application elevated or enter the credentials of an administrator account used to run the application. |

For example, the following launches `notepad.exe` and open the text file `C:\Windows\System32\drivers\etc\hosts` which can only be modified with elevated privileges (as an Administrator) :
```xml
<exec path="C:\Windows\notepad.exe" arguments="C:\Windows\System32\drivers\etc\hosts" verb="runas" />
```
To get extended information about verbs, see the following Microsoft documentation article: [ShellExecute and ShellExecuteEx, Object Verbs](https://docs.microsoft.com/en-us/windows/win32/shell/launch#object-verbs).



### &lt;open&gt; action ###

The &lt;open&gt; element is used to open a document by the default associated application. The &lt;open&gt; element must be added under the &lt;actions&gt; element.
Expand Down
30 changes: 29 additions & 1 deletion include/shellanything/ActionExecute.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace shellanything
/// </summary>
/// <param name="iContext">The current context of execution.</param>
/// <returns>Returns true if the execution is successful. Returns false otherwise.</returns>
virtual bool Execute(const Context & iContext) const;
virtual bool Execute(const Context& iContext) const;

/// <summary>
/// Getter for the 'path' parameter.
Expand Down Expand Up @@ -76,10 +76,38 @@ namespace shellanything
/// </summary>
void SetArguments(const std::string & iArguments);

/// <summary>
/// Getter for the 'verb' parameter.
/// </summary>
const std::string& GetVerb() const;

/// <summary>
/// Setter for the 'verb' parameter.
/// </summary>
void SetVerb(const std::string& iVerb);

private:
/// <summary>
/// Execute an application with ShellExecuteEx method.
/// This execute method supports verbs.
/// </summary>
/// <param name="iContext">The current context of execution.</param>
/// <returns>Returns true if the execution is successful. Returns false otherwise.</returns>
virtual bool ExecuteVerb(const Context & iContext) const;

/// <summary>
/// Execute an application with RapidAssist method.
/// This execute method does not supports verbs.
/// </summary>
/// <param name="iContext">The current context of execution.</param>
/// <returns>Returns true if the execution is successful. Returns false otherwise.</returns>
virtual bool ExecuteProcess(const Context & iContext) const;

private:
std::string mPath;
std::string mBaseDir;
std::string mArguments;
std::string mVerb;
};

} //namespace shellanything
Expand Down
106 changes: 98 additions & 8 deletions src/ActionExecute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "rapidassist/filesystem_utf8.h"
#include "PropertyManager.h"

#include <windows.h>
#pragma warning( push )
#pragma warning( disable: 4355 ) // glog\install_dir\include\glog/logging.h(1167): warning C4355: 'this' : used in base member initializer list
#include <glog/logging.h>
Expand All @@ -45,11 +46,81 @@ namespace shellanything
{
}

bool ActionExecute::Execute(const Context & iContext) const
bool ActionExecute::Execute(const Context& iContext) const
{
PropertyManager & pmgr = PropertyManager::GetInstance();
std::string path = pmgr.Expand(mPath);
std::string basedir = pmgr.Expand(mBaseDir);
PropertyManager& pmgr = PropertyManager::GetInstance();
std::string verb = pmgr.Expand(mVerb);

//If a verb was specified, delegate to VerbExecute(). Otherwise, use ProcessExecute().
if (verb.empty())
return ExecuteProcess(iContext);
else
return ExecuteVerb(iContext);
}

bool ActionExecute::ExecuteVerb(const Context& iContext) const
{
PropertyManager& pmgr = PropertyManager::GetInstance();
std::string path = pmgr.Expand(mPath);
std::string basedir = pmgr.Expand(mBaseDir);
std::string arguments = pmgr.Expand(mArguments);
std::string verb = pmgr.Expand(mVerb);

std::wstring pathW = ra::unicode::Utf8ToUnicode(path);
std::wstring argumentsW = ra::unicode::Utf8ToUnicode(arguments);
std::wstring basedirW = ra::unicode::Utf8ToUnicode(basedir);
std::wstring verbW = ra::unicode::Utf8ToUnicode(verb);

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.lpFile = pathW.c_str();

//Print execute values in the logs
LOG(INFO) << "Exec: '" << path << "'.";
if (!verb.empty())
{
info.lpVerb = verbW.c_str(); // Verb
LOG(INFO) << "Verb: '" << verb << "'.";
}
if (!arguments.empty())
{
info.lpParameters = argumentsW.c_str(); // Arguments
LOG(INFO) << "Arguments: '" << arguments << "'.";
}
if (!basedir.empty())
{
info.lpDirectory = basedirW.c_str(); // Default directory
LOG(INFO) << "Basedir: '" << basedir << "'.";
}

//Execute and get the pid
bool success = (ShellExecuteExW(&info) == TRUE);
if (!success)
return false;
DWORD pId = GetProcessId(info.hProcess);

success = (pId != ra::process::INVALID_PROCESS_ID);
if (success)
{
LOG(INFO) << "Process created. PID=" << pId;
}

return success;
}

bool ActionExecute::ExecuteProcess(const Context & iContext) const
{
PropertyManager& pmgr = PropertyManager::GetInstance();
std::string path = pmgr.Expand(mPath);
std::string basedir = pmgr.Expand(mBaseDir);
std::string arguments = pmgr.Expand(mArguments);

bool basedir_missing = basedir.empty();
Expand Down Expand Up @@ -94,20 +165,29 @@ namespace shellanything
LOG(WARNING) << "attribute 'basedir' not specified.";
}

//debug
//Print execute values in the logs
LOG(INFO) << "Exec: '" << path << "'.";
if (!arguments.empty())
{
LOG(INFO) << "Arguments: '" << arguments << "'.";
}
if (!basedir.empty())
{
LOG(INFO) << "Basedir: '" << basedir << "'.";
}

//Execute and get the pid
uint32_t pId = ra::process::INVALID_PROCESS_ID;
if (arguments_missing)
{
LOG(INFO) << "Running '" << path << "' from directory '" << basedir << "'.";
pId = ra::process::StartProcessUtf8(path, basedir);
}
else
{
LOG(INFO) << "Running '" << path << "' from directory '" << basedir << "' with arguments '" << arguments << "'.";
pId = ra::process::StartProcessUtf8(path, basedir, arguments);
}

bool success = pId != ra::process::INVALID_PROCESS_ID;
bool success = (pId != ra::process::INVALID_PROCESS_ID);
if (success)
{
LOG(INFO) << "Process created. PID=" << pId;
Expand Down Expand Up @@ -146,4 +226,14 @@ namespace shellanything
mArguments = iArguments;
}

const std::string& ActionExecute::GetVerb() const
{
return mVerb;
}

void ActionExecute::SetVerb(const std::string& iVerb)
{
mVerb = iVerb;
}

} //namespace shellanything
4 changes: 2 additions & 2 deletions src/ActionOpen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ namespace shellanything
info.nShow = SW_SHOWDEFAULT;
info.lpVerb = L"open";
info.lpFile = pathW.c_str();
info.lpParameters = NULL; //arguments
info.lpDirectory = NULL; // default directory
info.lpParameters = NULL; // arguments
info.lpDirectory = NULL; // Default directory

BOOL success = ShellExecuteExW(&info);
return (success == TRUE);
Expand Down
8 changes: 8 additions & 0 deletions src/ObjectFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,14 @@ namespace shellanything
action->SetBaseDir(tmp_str);
}

//parse verb
tmp_str = "";
tmp_int = -1;
if (ParseAttribute(element, "verb", true, true, tmp_str, error))
{
action->SetVerb(tmp_str);
}

//done parsing
return action;
}
Expand Down
Loading

0 comments on commit 1af4c0c

Please sign in to comment.