diff --git a/Docs/src/compiler.but b/Docs/src/compiler.but index 2fa27c7f..5c1aebe6 100644 --- a/Docs/src/compiler.but +++ b/Docs/src/compiler.but @@ -91,7 +91,7 @@ This command will issue an error to the script compiler and will stop execution \c command -This command will execute 'command' using a call to CreateProcess(). Unlike \R{system}{!system}, it does not use the command line processor, so input/output redirection and commands like 'cd', 'dir' and 'type' can not be used. \R{execute}{!execute} also ignores the return value of the executed command. Currently, the only known advantage of \R{execute}{!execute} over \R{system}{!system} is that it does not give trouble when the current working directory is specified using UNC. +This command will execute 'command' using a call to CreateProcess(). Unlike \R{system}{!system}, it does not use the command line processor, so input/output redirection and commands like 'cd', 'dir' and 'type' can not be used. Currently, the only known advantage of \R{execute}{!execute} over \R{system}{!system} is that it does not give trouble when the current working directory is specified using UNC. On POSIX platforms, \R{execute}{!execute} will use system() just like \R{system}{!system}. diff --git a/Docs/src/history.but b/Docs/src/history.but index f00c0937..1f6b14da 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -24,6 +24,8 @@ Released on ?, 2014 \b !system will decode child output as OEMCP if GetConsoleOutputCP() == GetOEMCP() +\b !execute supports comparing the exit code with the same syntax as !system + \H{v3.0a2} 3.0 Alpha 2 Released on December 24th, 2013 diff --git a/Source/script.cpp b/Source/script.cpp index 3569a95b..ef661522 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -3186,17 +3186,38 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } return PS_OK; case TOK_P_SYSTEMEXEC: + case TOK_P_EXECUTE: { + const TCHAR *cmdname=get_commandtoken_name(which_token); TCHAR *exec=line.gettoken_str(1); int comp=line.gettoken_enum(2,_T("<\0>\0<>\0=\0ignore\0")); if (line.getnumtokens() == 2) comp = 4; if (comp == -1 && line.getnumtokens() == 3) comp=4; if (comp == -1) PRINTHELP() - int success=0; + int success=0, ret; int cmpv=line.gettoken_int(3,&success); if (!success && comp != 4) PRINTHELP() - SCRIPT_MSG(_T("!system: \"%") NPRIs _T("\"\n"),exec); - int ret=sane_system(exec); + SCRIPT_MSG(_T("%") NPRIs _T(": \"%") NPRIs _T("\"\n"),cmdname,exec); +#ifdef _WIN32 + if (TOK_P_EXECUTE == which_token) + { +#ifdef _UNICODE + ret=RunChildProcessRedirected(0,exec); +#else + ret=-1; + PROCESS_INFORMATION pi; + STARTUPINFO si={sizeof(STARTUPINFO),}; + if (CreateProcess(NULL,exec,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) + { + WaitForSingleObject(pi.hProcess,INFINITE); + if (GetExitCodeProcess(pi.hProcess, &si.cb)) ret=(int)si.cb; + CloseHandle(pi.hThread), CloseHandle(pi.hProcess); + } +#endif + } + else +#endif //~ _WIN32 + ret=sane_system(exec); if (comp == 0 && ret < cmpv); else if (comp == 1 && ret > cmpv); else if (comp == 2 && ret != cmpv); @@ -3204,33 +3225,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) else if (comp == 4); else { - ERROR_MSG(_T("!system: returned %d, aborting\n"),ret); + ERROR_MSG(_T("%") NPRIs _T(": returned %d, aborting\n"),cmdname,ret); return PS_ERROR; } - SCRIPT_MSG(_T("!system: returned %d\n"),ret); + SCRIPT_MSG(_T("%") NPRIs _T(": returned %d\n"),cmdname,ret); } return PS_OK; - case TOK_P_EXECUTE: - { - TCHAR *exec=line.gettoken_str(1); - SCRIPT_MSG(_T("!execute: \"%") NPRIs _T("\"\n"),exec); -#ifdef _WIN32 -#ifdef _UNICODE - RunChildProcessRedirected(0,exec); -#else - PROCESS_INFORMATION pi; - STARTUPINFO si={sizeof(STARTUPINFO),}; - if (CreateProcess(NULL,exec,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) - { - WaitForSingleObject(pi.hProcess,INFINITE); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - } -#endif -#else - sane_system(exec); -#endif - } case TOK_P_ADDINCLUDEDIR: { TCHAR *f = line.gettoken_str(1); diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 5a2732da..c117dd0c 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -244,8 +244,8 @@ static tokenType tokenlist[TOK__LAST] = {TOK_MANIFEST_SUPPORTEDOS,_T("ManifestSupportedOS"),1,-1,_T("none|all|WinVista|Win7|Win8|Win8.1|{GUID} [...]"),TP_GLOBAL}, {TOK_P_PACKEXEHEADER,_T("!packhdr"),2,0,_T("temp_file_name command_line_to_compress_that_temp_file"),TP_ALL}, {TOK_P_FINALIZE,_T("!finalize"),1,0,_T("command_with_%1"),TP_ALL}, -{TOK_P_SYSTEMEXEC,_T("!system"),1,2,_T("command [<|>|<>|=) retval]"),TP_ALL}, -{TOK_P_EXECUTE,_T("!execute"),1,0,_T("command"),TP_ALL}, +{TOK_P_SYSTEMEXEC,_T("!system"),1,2,_T("command [<|>|<>|= retval]"),TP_ALL}, +{TOK_P_EXECUTE, _T("!execute"),1,2,_T("command [<|>|<>|= retval]"),TP_ALL}, {TOK_P_ADDINCLUDEDIR,_T("!AddIncludeDir"),1,0,_T("dir"),TP_ALL}, {TOK_P_INCLUDE,_T("!include"),1,2,_T("[/NONFATAL] [/CHARSET=<") TSTR_INPUTCHARSET _T(">] filename.nsh"),TP_ALL}, {TOK_P_CD,_T("!cd"),1,0,_T("absolute_or_relative_new_directory"),TP_ALL},