mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Added environment variable expansion to the command line handling of desktop actions, plus the special '%AlfrescoDir%' token for the
current working directory path (from the client side). Updated sample commandline test action to use '%SystemRoot%\Notepad.exe'. Added lock check to check out action code to give more meaningful error message. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3689 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Binary file not shown.
@@ -37,14 +37,14 @@ using namespace Alfresco;
|
|||||||
|
|
||||||
// CCAlfrescoAppApp
|
// CCAlfrescoAppApp
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(CCAlfrescoAppApp, CWinApp)
|
BEGIN_MESSAGE_MAP(CAlfrescoApp, CWinApp)
|
||||||
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
|
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
// CCAlfrescoAppApp construction
|
// CCAlfrescoApp construction
|
||||||
|
|
||||||
CCAlfrescoAppApp::CCAlfrescoAppApp()
|
CAlfrescoApp::CAlfrescoApp()
|
||||||
{
|
{
|
||||||
// TODO: add construction code here,
|
// TODO: add construction code here,
|
||||||
// Place all significant initialization in InitInstance
|
// Place all significant initialization in InitInstance
|
||||||
@@ -53,12 +53,12 @@ CCAlfrescoAppApp::CCAlfrescoAppApp()
|
|||||||
|
|
||||||
// The one and only CCAlfrescoAppApp object
|
// The one and only CCAlfrescoAppApp object
|
||||||
|
|
||||||
CCAlfrescoAppApp theApp;
|
CAlfrescoApp theApp;
|
||||||
|
|
||||||
|
|
||||||
// CCAlfrescoAppApp initialization
|
// CCAlfrescoAppApp initialization
|
||||||
|
|
||||||
BOOL CCAlfrescoAppApp::InitInstance()
|
BOOL CAlfrescoApp::InitInstance()
|
||||||
{
|
{
|
||||||
// InitCommonControls() is required on Windows XP if an application
|
// InitCommonControls() is required on Windows XP if an application
|
||||||
// manifest specifies use of ComCtl32.dll version 6 or later to enable
|
// manifest specifies use of ComCtl32.dll version 6 or later to enable
|
||||||
@@ -181,8 +181,8 @@ BOOL CCAlfrescoAppApp::InitInstance()
|
|||||||
* @param params DesktopParams&
|
* @param params DesktopParams&
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
bool CCAlfrescoAppApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringList& paths, AlfrescoActionInfo& actionInfo,
|
bool CAlfrescoApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringList& paths, AlfrescoActionInfo& actionInfo,
|
||||||
DesktopParams& params) {
|
DesktopParams& params) {
|
||||||
|
|
||||||
// If there are no paths then just return a success
|
// If there are no paths then just return a success
|
||||||
|
|
||||||
@@ -401,7 +401,7 @@ bool CCAlfrescoAppApp::buildDesktopParameters( AlfrescoInterface& alfresco, Stri
|
|||||||
* @param aborted bool&
|
* @param aborted bool&
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
bool CCAlfrescoAppApp::copyFilesUsingShell(const String& fromFileFolder, const String& toFolder, bool& aborted) {
|
bool CAlfrescoApp::copyFilesUsingShell(const String& fromFileFolder, const String& toFolder, bool& aborted) {
|
||||||
|
|
||||||
// Build the from/to paths, must be double null terminated
|
// Build the from/to paths, must be double null terminated
|
||||||
|
|
||||||
@@ -456,7 +456,7 @@ bool CCAlfrescoAppApp::copyFilesUsingShell(const String& fromFileFolder, const S
|
|||||||
* @param actionInfo AlfrescoActionInfo&
|
* @param actionInfo AlfrescoActionInfo&
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo) {
|
bool CAlfrescoApp::runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo) {
|
||||||
|
|
||||||
// Build the desktop action parameter list, perform any file copying of local files
|
// Build the desktop action parameter list, perform any file copying of local files
|
||||||
|
|
||||||
@@ -484,24 +484,9 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL
|
|||||||
|
|
||||||
if ( response.getStatus() == StsCommandLine) {
|
if ( response.getStatus() == StsCommandLine) {
|
||||||
|
|
||||||
// Initialize the startup information
|
|
||||||
|
|
||||||
STARTUPINFO startupInfo;
|
|
||||||
memset(&startupInfo, 0, sizeof(STARTUPINFO));
|
|
||||||
|
|
||||||
// Launch a process using the command line
|
// Launch a process using the command line
|
||||||
|
|
||||||
PROCESS_INFORMATION processInfo;
|
sts = doCommandLine( alfresco, response.getStatusMessage());
|
||||||
memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
|
|
||||||
|
|
||||||
if ( CreateProcess( response.getStatusMessage().data(), NULL, NULL, NULL, true, 0, NULL, NULL,
|
|
||||||
&startupInfo, &processInfo) == false) {
|
|
||||||
CString msg;
|
|
||||||
msg.FormatMessage( L"Failed to launch command line\n\n%1\n\nError %2!d!", response.getStatusMessage().data(), GetLastError());
|
|
||||||
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sts = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a web browser should be launched with a URL
|
// Check if a web browser should be launched with a URL
|
||||||
@@ -510,14 +495,7 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL
|
|||||||
|
|
||||||
// Use the Windows shell to open the URL
|
// Use the Windows shell to open the URL
|
||||||
|
|
||||||
HINSTANCE shellSts = ShellExecute( NULL, NULL, response.getStatusMessage().data(), NULL, NULL, SW_SHOWNORMAL);
|
sts = doURL( alfresco, response.getStatusMessage());
|
||||||
if (( int) shellSts < 32) {
|
|
||||||
CString msg;
|
|
||||||
msg.FormatMessage( L"Failed to launch URL\n\n%1", response.getStatusMessage().data());
|
|
||||||
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sts = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error status
|
// Error status
|
||||||
@@ -572,3 +550,168 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL
|
|||||||
|
|
||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch a command line
|
||||||
|
*
|
||||||
|
* @param alfresco AlfrescoInterface&
|
||||||
|
* @param cmdStr const String&
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool CAlfrescoApp::doCommandLine( AlfrescoInterface& alfresco, const String& cmdStr) {
|
||||||
|
|
||||||
|
// Check if the command line contains any environment variables/tokens
|
||||||
|
|
||||||
|
String cmdLine = cmdStr;
|
||||||
|
int pos = cmdLine.indexOf( L'%');
|
||||||
|
|
||||||
|
if ( pos != -1) {
|
||||||
|
|
||||||
|
// Command line contains environment variables or other tokens that must be replaced
|
||||||
|
|
||||||
|
String newCmdLine = L"";
|
||||||
|
if (pos > 0)
|
||||||
|
newCmdLine = cmdLine.substring( 0, pos);
|
||||||
|
|
||||||
|
wchar_t envBuf[256];
|
||||||
|
size_t envLen;
|
||||||
|
|
||||||
|
while ( pos != -1) {
|
||||||
|
|
||||||
|
// Find the end of the current token
|
||||||
|
|
||||||
|
int endPos = cmdLine.indexOf ( L'%', pos + 1);
|
||||||
|
|
||||||
|
if ( endPos == -1) {
|
||||||
|
CString msg;
|
||||||
|
msg.FormatMessage( L"Bad token in command line\n\n%1", cmdLine.data());
|
||||||
|
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the token
|
||||||
|
|
||||||
|
String token = cmdLine.substring( pos + 1, endPos);
|
||||||
|
|
||||||
|
// Replace the token with an environment variable value or other values
|
||||||
|
|
||||||
|
if ( token.equals( L"AlfrescoDir")) {
|
||||||
|
|
||||||
|
// Use the local path to the Alfresco folder that the application is running from
|
||||||
|
|
||||||
|
newCmdLine.append( alfresco.getUNCPath());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Find the environment variable value
|
||||||
|
|
||||||
|
envLen = sizeof( envBuf)/sizeof(wchar_t);
|
||||||
|
const wchar_t* pEnvName = token.data();
|
||||||
|
|
||||||
|
if ( _wgetenv_s( &envLen, envBuf, envLen, pEnvName) == 0) {
|
||||||
|
|
||||||
|
// Append the environment variable value
|
||||||
|
|
||||||
|
newCmdLine.append( envBuf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Error converting the environment variable
|
||||||
|
|
||||||
|
CString msg;
|
||||||
|
msg.FormatMessage( L"Failed to convert environment variable\n\n%1\n\n%2", token.data(), cmdLine.data());
|
||||||
|
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the token search position
|
||||||
|
|
||||||
|
pos = endPos + 1;
|
||||||
|
|
||||||
|
if (( unsigned int) pos < cmdStr.length()) {
|
||||||
|
|
||||||
|
// Search for the next token
|
||||||
|
|
||||||
|
pos = cmdLine.indexOf( L'%', pos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// End of string, finish the token search
|
||||||
|
|
||||||
|
pos = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the normal string between tokens
|
||||||
|
|
||||||
|
if ( pos > (endPos + 1)) {
|
||||||
|
|
||||||
|
// Get the between token sting
|
||||||
|
|
||||||
|
String filler = cmdLine.substring( endPos + 1, pos);
|
||||||
|
newCmdLine.append( filler);
|
||||||
|
}
|
||||||
|
else if ( pos == -1) {
|
||||||
|
|
||||||
|
// Append the remaining string
|
||||||
|
|
||||||
|
String filler = cmdLine.substring( endPos + 1);
|
||||||
|
newCmdLine.append( filler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the command line
|
||||||
|
|
||||||
|
cmdLine = newCmdLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the startup information
|
||||||
|
|
||||||
|
STARTUPINFO startupInfo;
|
||||||
|
memset(&startupInfo, 0, sizeof(STARTUPINFO));
|
||||||
|
|
||||||
|
// Launch a process using the command line
|
||||||
|
|
||||||
|
PROCESS_INFORMATION processInfo;
|
||||||
|
memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
|
||||||
|
|
||||||
|
bool sts = false;
|
||||||
|
|
||||||
|
if ( CreateProcess( NULL, (LPWSTR) cmdLine.data(), NULL, NULL, true, 0, NULL, NULL,
|
||||||
|
&startupInfo, &processInfo) == false) {
|
||||||
|
CString msg;
|
||||||
|
msg.FormatMessage( L"Failed to launch command line\n\n%1\n\nError %2!d!", cmdLine.data(), GetLastError());
|
||||||
|
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sts = true;
|
||||||
|
|
||||||
|
return sts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Browse to a URL
|
||||||
|
*
|
||||||
|
* @param alfresco AlfrescoInterface&
|
||||||
|
* @param url const String&
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool CAlfrescoApp::doURL( AlfrescoInterface& alfresco, const String& url) {
|
||||||
|
|
||||||
|
// Use the Windows shell to open the URL
|
||||||
|
|
||||||
|
bool sts = false;
|
||||||
|
|
||||||
|
HINSTANCE shellSts = ShellExecute( NULL, NULL, url.data(), NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
if (( int) shellSts < 32) {
|
||||||
|
CString msg;
|
||||||
|
msg.FormatMessage( L"Failed to launch URL\n\n%1", url.data());
|
||||||
|
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sts = true;
|
||||||
|
|
||||||
|
return sts;
|
||||||
|
}
|
||||||
|
@@ -30,14 +30,14 @@
|
|||||||
|
|
||||||
using namespace Alfresco;
|
using namespace Alfresco;
|
||||||
|
|
||||||
// CCAlfrescoAppApp:
|
// CAlfrescoApp:
|
||||||
// See CAlfrescoApp.cpp for the implementation of this class
|
// See CAlfrescoApp.cpp for the implementation of this class
|
||||||
//
|
//
|
||||||
|
|
||||||
class CCAlfrescoAppApp : public CWinApp
|
class CAlfrescoApp : public CWinApp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CCAlfrescoAppApp();
|
CAlfrescoApp();
|
||||||
|
|
||||||
// Overrides
|
// Overrides
|
||||||
public:
|
public:
|
||||||
@@ -59,6 +59,11 @@ private:
|
|||||||
// Run the action
|
// Run the action
|
||||||
|
|
||||||
bool runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo);
|
bool runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo);
|
||||||
|
|
||||||
|
// Post-process actions, command line launch and browse to URL
|
||||||
|
|
||||||
|
bool doCommandLine( AlfrescoInterface& alfresco, const String& cmdLine);
|
||||||
|
bool doURL( AlfrescoInterface& alfresco, const String& url);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CCAlfrescoAppApp theApp;
|
extern CAlfrescoApp theApp;
|
@@ -676,7 +676,8 @@ void String::append ( const char* str) {
|
|||||||
* @param str const wchar_t*
|
* @param str const wchar_t*
|
||||||
*/
|
*/
|
||||||
void String::append (const wchar_t* str) {
|
void String::append (const wchar_t* str) {
|
||||||
m_string += str;
|
while ( *str != 0)
|
||||||
|
m_string += *str++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -113,6 +113,11 @@ public class CheckInOutDesktopAction extends DesktopAction {
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
// Dump the error
|
||||||
|
|
||||||
|
if ( logger.isErrorEnabled())
|
||||||
|
logger.error("Desktop action error", ex);
|
||||||
|
|
||||||
// Return an error status and message
|
// Return an error status and message
|
||||||
|
|
||||||
response.setStatus(StsError, "Checkin failed for " + target.getTarget() + ", " + ex.getMessage());
|
response.setStatus(StsError, "Checkin failed for " + target.getTarget() + ", " + ex.getMessage());
|
||||||
@@ -122,6 +127,19 @@ public class CheckInOutDesktopAction extends DesktopAction {
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Check if the file is locked
|
||||||
|
|
||||||
|
if ( getNodeService().hasAspect( target.getNode(), ContentModel.ASPECT_LOCKABLE)) {
|
||||||
|
|
||||||
|
// Get the lock type
|
||||||
|
|
||||||
|
String lockTypeStr = (String) getNodeService().getProperty( target.getNode(), ContentModel.PROP_LOCK_TYPE);
|
||||||
|
if ( lockTypeStr != null) {
|
||||||
|
response.setStatus(StsError, "Checkout failed, file is locked");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check out the file
|
// Check out the file
|
||||||
|
|
||||||
NodeRef workingCopyNode = getCheckInOutService().checkout( target.getNode());
|
NodeRef workingCopyNode = getCheckInOutService().checkout( target.getNode());
|
||||||
@@ -149,6 +167,11 @@ public class CheckInOutDesktopAction extends DesktopAction {
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
// Dump the error
|
||||||
|
|
||||||
|
if ( logger.isErrorEnabled())
|
||||||
|
logger.error("Desktop action error", ex);
|
||||||
|
|
||||||
// Return an error status and message
|
// Return an error status and message
|
||||||
|
|
||||||
response.setStatus(StsError, "Failed to checkout " + target.getTarget() + ", " + ex.getMessage());
|
response.setStatus(StsError, "Failed to checkout " + target.getTarget() + ", " + ex.getMessage());
|
||||||
|
@@ -47,6 +47,6 @@ public class CmdLineDesktopAction extends DesktopAction {
|
|||||||
|
|
||||||
// Return a URL in the status message
|
// Return a URL in the status message
|
||||||
|
|
||||||
return new DesktopResponse(StsCommandLine, "C:\\Windows\\notepad.exe");
|
return new DesktopResponse(StsCommandLine, "%SystemRoot%\\notepad.exe");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user