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
|
||||
|
||||
\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" "$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
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ Released on ? ?th, 2017
|
|||
|
||||
\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})
|
||||
|
||||
\S2{} Minor Changes
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -176,6 +176,7 @@ enum
|
|||
TOK_EXEC,
|
||||
TOK_EXECWAIT,
|
||||
TOK_EXECSHELL,
|
||||
TOK_EXECSHELLWAIT,
|
||||
TOK_CALLINSTDLL,
|
||||
TOK_REGDLL,
|
||||
TOK_UNREGDLL,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue