Added ExecShellWait

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6839 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2017-03-21 22:04:40 +00:00
parent 7650898389
commit 024e01a71e
9 changed files with 60 additions and 31 deletions

View file

@ -876,20 +876,29 @@ static int NSISCALL ExecuteEntry(entry *entry_)
#ifdef NSIS_SUPPORT_SHELLEXECUTE
case EW_SHELLEXEC: // this uses improvements of Andras Varga
{
int x;
TCHAR *buf0=GetStringFromParm(0x00);
TCHAR *buf3=GetStringFromParm(0x31);
TCHAR *buf2=GetStringFromParm(0x22);
SHELLEXECUTEINFO sei;
TCHAR *buf0=GetStringFromParm(0x00); // Verb
TCHAR *buf3=GetStringFromParm(0x31); // File
TCHAR *buf2=GetStringFromParm(0x22); // Parameters
GetStringFromParm(0x15); // For update_status_text_buf1
update_status_text_buf1(LANG_EXECSHELL);
x=(int)(INT_PTR)ShellExecute(g_hwnd,buf0[0]?buf0:NULL,buf3,buf2[0]?buf2:NULL,state_output_directory,parm3);
if (x < 33)
sei.cbSize=sizeof(SHELLEXECUTEINFO);
sei.fMask=parm4;
sei.hwnd=g_hwnd, sei.nShow=parm3;
sei.lpVerb=buf0[0]?buf0:NULL, sei.lpFile=buf3, sei.lpParameters=buf2[0]?buf2:NULL, sei.lpDirectory=state_output_directory;
sei.lpIDList=NULL; // Must set this because SEE_MASK_INVOKEIDLIST might be set
if (!ShellExecuteEx(&sei))
{
log_printf5(_T("ExecShell: warning: error (\"%s\": file:\"%s\" params:\"%s\")=%d"),buf0,buf3,buf2,x);
exec_error++;
}
else
{
if (SEE_MASK_NOCLOSEPROCESS & sei.fMask)
{
WaitForProcess(sei.hProcess);
CloseHandle(sei.hProcess);
}
log_printf4(_T("ExecShell: success (\"%s\": file:\"%s\" params:\"%s\")"),buf0,buf3,buf2);
}
}
@ -910,17 +919,11 @@ static int NSISCALL ExecuteEntry(entry *entry_)
log_printf2(_T("Exec: success (\"%s\")"),buf0);
if (parm2)
{
DWORD lExitCode;
while (WaitForSingleObject(hProc,100) == WAIT_TIMEOUT)
{
MessageLoop(WM_PAINT);
}
GetExitCodeProcess(hProc, &lExitCode);
DWORD lExitCode=WaitForProcess(hProc);
if (parm1>=0) myitoa(var1,lExitCode);
else if (lExitCode) exec_error++;
}
CloseHandle( hProc );
CloseHandle(hProc);
}
else
{

View file

@ -50,7 +50,7 @@
enum
{
EW_INVALID_OPCODE, // zero is invalid. useful for catching errors. (otherwise an all zeroes instruction
// does nothing, which is easily ignored but means something is wrong.
// does nothing, which is easily ignored but means something is wrong)
EW_RET, // return from function call
EW_NOP, // Nop/Jump, do nothing: 1, [?new address+1:advance one]
EW_ABORT, // Abort: 1 [status]
@ -118,7 +118,7 @@ enum
#endif
#ifdef NSIS_SUPPORT_SHELLEXECUTE
EW_SHELLEXEC, // ShellExecute program: 4, [shell action, complete commandline, parameters, showwindow]
EW_SHELLEXEC, // ShellExecute program: 5, [SEE_MASK_FLAG_*, verb, file, parameters, showwindow] (Will wait if SEE_MASK_NOCLOSEPROCESS is set)
#endif
#ifdef NSIS_SUPPORT_EXECUTE

View file

@ -1192,3 +1192,13 @@ void * NSISCALL NSISGetProcAddress(HANDLE dllHandle, TCHAR* funcName)
return GetProcAddress(dllHandle, funcName);
#endif
}
DWORD NSISCALL WaitForProcess(HANDLE hProcess)
{
DWORD excod;
while (WaitForSingleObject(hProcess, 100) == WAIT_TIMEOUT)
MessageLoop(WM_PAINT);
GetExitCodeProcess(hProcess, &excod);
return excod;
}

View file

@ -157,7 +157,9 @@ void NSISCALL MessageLoop(UINT uCheckedMsg);
* @param funcName The name of the function to get the address of.
* @return The pointer to the function. Null if failure.
*/
void * NSISCALL NSISGetProcAddress(HANDLE dllHandle, TCHAR* funcName);
void* NSISCALL NSISGetProcAddress(HANDLE dllHandle, TCHAR* funcName);
DWORD NSISCALL WaitForProcess(HANDLE hProcess);
// Turn a pair of chars into a word
// Turn four chars into a dword

View file

@ -4135,25 +4135,28 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ERROR_MSG(_T("Error: %") NPRIs _T(" specified, NSIS_SUPPORT_EXECUTE not defined.\n"), line.gettoken_str(0));
return PS_ERROR;
#endif//!NSIS_SUPPORT_EXECUTE
case TOK_EXECSHELL: // this uses improvements of Andras Varga
case TOK_EXECSHELL:
case TOK_EXECSHELLWAIT:
#ifdef NSIS_SUPPORT_SHELLEXECUTE
{
const TCHAR *verb=line.gettoken_str(1), *file=line.gettoken_str(2), *params=line.gettoken_str(3);
UINT to=0, xflags=0;
static const TCHAR*fn=_T("/INVOKEIDLIST\0/CONNECTNETDRV\0/DOENVSUBST\0/NOIDLIST\0/NOCONSOLE\0/NOZONECHECKS\0/WAITFORINPUTIDLE\0/LOGUSAGE\0/ASYNCOK\0");
static const UINT fv[]={ 0x0000000C, 0x00000080, 0x00000200, 0x00001000,0x00008000, 0x00800000, 0x02000000, 0x04000000,0x00100000 };
for (int k;;) if ((k = line.gettoken_enum(to+1,fn)) < 0) { if (line.gettoken_str(to+1)[0]=='/') PRINTHELP(); break; } else xflags|=fv[k], to++;
const TCHAR *verb=line.gettoken_str(to+1), *file=line.gettoken_str(to+2), *params=line.gettoken_str(to+3), *cnam=get_commandtoken_name(which_token);
ent.which=EW_SHELLEXEC;
ent.offsets[0]=add_string(verb);
ent.offsets[1]=add_string(file);
ent.offsets[2]=add_string(params);
ent.offsets[3]=SW_SHOWNORMAL;
if (line.getnumtokens() > 4)
ent.offsets[0]=add_string(verb), ent.offsets[1]=add_string(file);
ent.offsets[2]=add_string(params), ent.offsets[3]=SW_SHOWNORMAL;
ent.offsets[4]=SEE_MASK_FLAG_NO_UI|SEE_MASK_FLAG_DDEWAIT|xflags|(which_token==TOK_EXECSHELLWAIT ? SEE_MASK_NOCLOSEPROCESS : 0);
if (line.getnumtokens()-to > 4)
{
int tab[8]={SW_SHOWDEFAULT,SW_SHOWNORMAL,SW_SHOWMAXIMIZED,SW_SHOWMINIMIZED,SW_HIDE,SW_SHOW,SW_SHOWNA,SW_SHOWMINNOACTIVE};
int a=line.gettoken_enum(4,_T("SW_SHOWDEFAULT\0SW_SHOWNORMAL\0SW_SHOWMAXIMIZED\0SW_SHOWMINIMIZED\0SW_HIDE\0SW_SHOW\0SW_SHOWNA\0SW_SHOWMINNOACTIVE\0"));
if (a < 0) PRINTHELP()
ent.offsets[3]=tab[a];
int a=line.gettoken_enum(to+4,_T("SW_SHOWDEFAULT\0SW_SHOWNORMAL\0SW_SHOWMAXIMIZED\0SW_SHOWMINIMIZED\0SW_HIDE\0SW_SHOW\0SW_SHOWNA\0SW_SHOWMINNOACTIVE\0"));
if (a >= 0) ent.offsets[3]=tab[a]; else PRINTHELP()
}
tstring detail=tstring(verb)+(_T(" ")+!*verb)+tstring(file);
ent.offsets[5]=add_string(detail.c_str());
SCRIPT_MSG(_T("ExecShell: %") NPRIs _T(": \"%") NPRIs _T("\" \"%") NPRIs _T("\" %") NPRIs _T("\n"),verb,file,params,line.gettoken_str(4));
SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T(": \"%") NPRIs _T("\" \"%") NPRIs _T("\" %") NPRIs _T("\n"),cnam,verb,file,params,line.gettoken_str(to+4));
DefineInnerLangString(NLF_EXEC_SHELL);
}
return add_entry(&ent);

View file

@ -80,7 +80,8 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_EXCH,_T("Exch"),0,1,_T("[$(user_var)] | [stack_item_index]"),TP_CODE},
{TOK_EXEC,_T("Exec"),1,0,_T("command_line"),TP_CODE},
{TOK_EXECWAIT,_T("ExecWait"),1,1,_T("command_line [$(user_var: return value)]"),TP_CODE},
{TOK_EXECSHELL,_T("ExecShell"),2,2,_T("(open|print|etc) command_line [parameters [showmode]]\n showmode=(SW_SHOWNORMAL|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_HIDE|SW_SHOW)"),TP_CODE},
{TOK_EXECSHELL,_T("ExecShell"),2,11,_T("[flags] verb command_line [parameters [showmode]]\n verb=(open|print)\n showmode=(SW_SHOWNORMAL|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_HIDE|SW_SHOW)"),TP_CODE},
{TOK_EXECSHELLWAIT,_T("ExecShellWait"),2,11,_T("[flags] verb command_line [parameters [showmode]]"),TP_CODE},
{TOK_EXPANDENVSTRS,_T("ExpandEnvStrings"),2,0,_T("$(user_var: output) string"),TP_CODE},
{TOK_FINDWINDOW,_T("FindWindow"),2,3,_T("$(user_var: handle output) WindowClass [WindowTitle] [Window_Parent] [Child_After]"),TP_CODE},
{TOK_FINDCLOSE,_T("FindClose"),1,0,_T("$(user_var: handle input)"),TP_CODE},

View file

@ -176,6 +176,7 @@ enum
TOK_EXEC,
TOK_EXECWAIT,
TOK_EXECSHELL,
TOK_EXECSHELLWAIT,
TOK_CALLINSTDLL,
TOK_REGDLL,
TOK_UNREGDLL,