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:
parent
7650898389
commit
024e01a71e
9 changed files with 60 additions and 31 deletions
|
@ -27,13 +27,20 @@ Execute the specified program and continue immediately. Note that the file speci
|
||||||
|
|
||||||
\S2{execshell} ExecShell
|
\S2{execshell} ExecShell
|
||||||
|
|
||||||
\c action command [parameters] [SW_SHOWDEFAULT | SW_SHOWNORMAL | SW_SHOWMAXIMIZED | SW_SHOWMINIMIZED | SW_HIDE]
|
\c [/INVOKEIDLIST] action command [parameters] [SW_SHOWDEFAULT | SW_SHOWNORMAL | SW_SHOWMAXIMIZED | SW_SHOWMINIMIZED | SW_HIDE]
|
||||||
|
|
||||||
Execute the specified program using ShellExecute. Note that action is usually "open", "print", etc, but can be an empty string to use the default action. Parameters and the show type are optional. $OUTDIR is used as the working directory. The error flag is set if the process could not be launched.
|
Execute the specified program using ShellExecuteEx. Note that action is usually "open", "print", etc, but can be an empty string to use the default action. Parameters and the show type are optional. $OUTDIR is used as the working directory. The error flag is set if the process could not be launched.
|
||||||
|
|
||||||
\c ExecShell "open" "http://nsis.sf.net/"
|
\c ExecShell "open" "http://nsis.sf.net/"
|
||||||
\c ExecShell "open" "$INSTDIR\readme.txt"
|
\c ExecShell "open" "$INSTDIR\readme.txt"
|
||||||
\c ExecShell "print" "$INSTDIR\readme.txt"
|
\c ExecShell "print" "$INSTDIR\readme.txt"
|
||||||
|
\c ExecShell /INVOKEIDLIST "properties" "$TEMP"
|
||||||
|
|
||||||
|
\S2{execshellwait} ExecShellWait
|
||||||
|
|
||||||
|
\c [/INVOKEIDLIST] action command [parameters] [SW_SHOWDEFAULT | SW_SHOWNORMAL | SW_SHOWMAXIMIZED | SW_SHOWMINIMIZED | SW_HIDE]
|
||||||
|
|
||||||
|
Execute the specified program using ExecShell and wait for executed process to quit. It will only wait for executable files and not other file types nor URLs.
|
||||||
|
|
||||||
\S2{execwait} ExecWait
|
\S2{execwait} ExecWait
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ Released on ? ?th, 2017
|
||||||
|
|
||||||
\S2{} Major Changes
|
\S2{} Major Changes
|
||||||
|
|
||||||
|
\b Added \R{execshellwait}{ExecShellWait}
|
||||||
|
|
||||||
\b Added \R{writeregmultistr}{WriteRegMultiStr} (\W{http://sf.net/p/nsis/feature-requests/382}{RFE #382}, \W{http://sf.net/p/nsis/patches/219}{patch #219})
|
\b Added \R{writeregmultistr}{WriteRegMultiStr} (\W{http://sf.net/p/nsis/feature-requests/382}{RFE #382}, \W{http://sf.net/p/nsis/patches/219}{patch #219})
|
||||||
|
|
||||||
\S2{} Minor Changes
|
\S2{} Minor Changes
|
||||||
|
|
|
@ -876,20 +876,29 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
||||||
#ifdef NSIS_SUPPORT_SHELLEXECUTE
|
#ifdef NSIS_SUPPORT_SHELLEXECUTE
|
||||||
case EW_SHELLEXEC: // this uses improvements of Andras Varga
|
case EW_SHELLEXEC: // this uses improvements of Andras Varga
|
||||||
{
|
{
|
||||||
int x;
|
SHELLEXECUTEINFO sei;
|
||||||
TCHAR *buf0=GetStringFromParm(0x00);
|
TCHAR *buf0=GetStringFromParm(0x00); // Verb
|
||||||
TCHAR *buf3=GetStringFromParm(0x31);
|
TCHAR *buf3=GetStringFromParm(0x31); // File
|
||||||
TCHAR *buf2=GetStringFromParm(0x22);
|
TCHAR *buf2=GetStringFromParm(0x22); // Parameters
|
||||||
GetStringFromParm(0x15); // For update_status_text_buf1
|
GetStringFromParm(0x15); // For update_status_text_buf1
|
||||||
update_status_text_buf1(LANG_EXECSHELL);
|
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);
|
sei.cbSize=sizeof(SHELLEXECUTEINFO);
|
||||||
if (x < 33)
|
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);
|
log_printf5(_T("ExecShell: warning: error (\"%s\": file:\"%s\" params:\"%s\")=%d"),buf0,buf3,buf2,x);
|
||||||
exec_error++;
|
exec_error++;
|
||||||
}
|
}
|
||||||
else
|
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);
|
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);
|
log_printf2(_T("Exec: success (\"%s\")"),buf0);
|
||||||
if (parm2)
|
if (parm2)
|
||||||
{
|
{
|
||||||
DWORD lExitCode;
|
DWORD lExitCode=WaitForProcess(hProc);
|
||||||
while (WaitForSingleObject(hProc,100) == WAIT_TIMEOUT)
|
|
||||||
{
|
|
||||||
MessageLoop(WM_PAINT);
|
|
||||||
}
|
|
||||||
GetExitCodeProcess(hProc, &lExitCode);
|
|
||||||
|
|
||||||
if (parm1>=0) myitoa(var1,lExitCode);
|
if (parm1>=0) myitoa(var1,lExitCode);
|
||||||
else if (lExitCode) exec_error++;
|
else if (lExitCode) exec_error++;
|
||||||
}
|
}
|
||||||
CloseHandle( hProc );
|
CloseHandle(hProc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
EW_INVALID_OPCODE, // zero is invalid. useful for catching errors. (otherwise an all zeroes instruction
|
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_RET, // return from function call
|
||||||
EW_NOP, // Nop/Jump, do nothing: 1, [?new address+1:advance one]
|
EW_NOP, // Nop/Jump, do nothing: 1, [?new address+1:advance one]
|
||||||
EW_ABORT, // Abort: 1 [status]
|
EW_ABORT, // Abort: 1 [status]
|
||||||
|
@ -118,7 +118,7 @@ enum
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NSIS_SUPPORT_SHELLEXECUTE
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef NSIS_SUPPORT_EXECUTE
|
#ifdef NSIS_SUPPORT_EXECUTE
|
||||||
|
|
|
@ -1192,3 +1192,13 @@ void * NSISCALL NSISGetProcAddress(HANDLE dllHandle, TCHAR* funcName)
|
||||||
return GetProcAddress(dllHandle, funcName);
|
return GetProcAddress(dllHandle, funcName);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD NSISCALL WaitForProcess(HANDLE hProcess)
|
||||||
|
{
|
||||||
|
DWORD excod;
|
||||||
|
while (WaitForSingleObject(hProcess, 100) == WAIT_TIMEOUT)
|
||||||
|
MessageLoop(WM_PAINT);
|
||||||
|
|
||||||
|
GetExitCodeProcess(hProcess, &excod);
|
||||||
|
return excod;
|
||||||
|
}
|
||||||
|
|
|
@ -157,7 +157,9 @@ void NSISCALL MessageLoop(UINT uCheckedMsg);
|
||||||
* @param funcName The name of the function to get the address of.
|
* @param funcName The name of the function to get the address of.
|
||||||
* @return The pointer to the function. Null if failure.
|
* @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 a pair of chars into a word
|
||||||
// Turn four chars into a dword
|
// Turn four chars into a dword
|
||||||
|
|
|
@ -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));
|
ERROR_MSG(_T("Error: %") NPRIs _T(" specified, NSIS_SUPPORT_EXECUTE not defined.\n"), line.gettoken_str(0));
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
#endif//!NSIS_SUPPORT_EXECUTE
|
#endif//!NSIS_SUPPORT_EXECUTE
|
||||||
case TOK_EXECSHELL: // this uses improvements of Andras Varga
|
case TOK_EXECSHELL:
|
||||||
|
case TOK_EXECSHELLWAIT:
|
||||||
#ifdef NSIS_SUPPORT_SHELLEXECUTE
|
#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.which=EW_SHELLEXEC;
|
||||||
ent.offsets[0]=add_string(verb);
|
ent.offsets[0]=add_string(verb), ent.offsets[1]=add_string(file);
|
||||||
ent.offsets[1]=add_string(file);
|
ent.offsets[2]=add_string(params), ent.offsets[3]=SW_SHOWNORMAL;
|
||||||
ent.offsets[2]=add_string(params);
|
ent.offsets[4]=SEE_MASK_FLAG_NO_UI|SEE_MASK_FLAG_DDEWAIT|xflags|(which_token==TOK_EXECSHELLWAIT ? SEE_MASK_NOCLOSEPROCESS : 0);
|
||||||
ent.offsets[3]=SW_SHOWNORMAL;
|
if (line.getnumtokens()-to > 4)
|
||||||
if (line.getnumtokens() > 4)
|
|
||||||
{
|
{
|
||||||
int tab[8]={SW_SHOWDEFAULT,SW_SHOWNORMAL,SW_SHOWMAXIMIZED,SW_SHOWMINIMIZED,SW_HIDE,SW_SHOW,SW_SHOWNA,SW_SHOWMINNOACTIVE};
|
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"));
|
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) PRINTHELP()
|
if (a >= 0) ent.offsets[3]=tab[a]; else PRINTHELP()
|
||||||
ent.offsets[3]=tab[a];
|
|
||||||
}
|
}
|
||||||
tstring detail=tstring(verb)+(_T(" ")+!*verb)+tstring(file);
|
tstring detail=tstring(verb)+(_T(" ")+!*verb)+tstring(file);
|
||||||
ent.offsets[5]=add_string(detail.c_str());
|
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);
|
DefineInnerLangString(NLF_EXEC_SHELL);
|
||||||
}
|
}
|
||||||
return add_entry(&ent);
|
return add_entry(&ent);
|
||||||
|
|
|
@ -80,7 +80,8 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
{TOK_EXCH,_T("Exch"),0,1,_T("[$(user_var)] | [stack_item_index]"),TP_CODE},
|
{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_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_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_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_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},
|
{TOK_FINDCLOSE,_T("FindClose"),1,0,_T("$(user_var: handle input)"),TP_CODE},
|
||||||
|
|
|
@ -176,6 +176,7 @@ enum
|
||||||
TOK_EXEC,
|
TOK_EXEC,
|
||||||
TOK_EXECWAIT,
|
TOK_EXECWAIT,
|
||||||
TOK_EXECSHELL,
|
TOK_EXECSHELL,
|
||||||
|
TOK_EXECSHELLWAIT,
|
||||||
TOK_CALLINSTDLL,
|
TOK_CALLINSTDLL,
|
||||||
TOK_REGDLL,
|
TOK_REGDLL,
|
||||||
TOK_UNREGDLL,
|
TOK_UNREGDLL,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue