ShellExecWait: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(fixed broken stack code)
(Unuicode and 64-bit support)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{PageAuthor|Anders}}
{{PageAuthor|Anders}}
[[Category:Functions & Macros]]
<div style="background-color:#FFFFDD;border:1px solid #aaaa22;color:#333311;padding:0.4em"><b>Note:</b> NSIS v3.02 added basic support for <span style="font-family: monospace, monospace;">ExecShellWait</span>.</div>


Basic code for waiting on a "ExecShell" (Note that you can only wait on programs, not documents or URL's)
Basic code for waiting on a "ExecShell" (Note that you can only wait on programs, not documents or URL's)
Line 7: Line 10:
!include WinMessages.nsh
!include WinMessages.nsh


!macro ShellExecWait verb app param workdir show exitoutvar ;only app and show must be != "", every thing else is optional
#define SEE_MASK_NOCLOSEPROCESS 0x40  
#define SEE_MASK_NOCLOSEPROCESS 0x40  
System::Call '*(&i60)i.r0'
System::Store S
System::Call '*$0(i 60,i 0x40,i $hwndparent,i,t "calc.exe",i ,i,i ${SW_SHOW})i.r0'
!if "${NSIS_PTR_SIZE}" > 4
System::Call 'shell32::ShellExecuteEx(ir0)i.r1 ?e'
!define /ReDef /math SYSSIZEOF_SHELLEXECUTEINFO 14 * ${NSIS_PTR_SIZE}
!else ifndef SYSSIZEOF_SHELLEXECUTEINFO
!define SYSSIZEOF_SHELLEXECUTEINFO 60
!endif
System::Call '*(&i${SYSSIZEOF_SHELLEXECUTEINFO})i.r0'
System::Call '*$0(i ${SYSSIZEOF_SHELLEXECUTEINFO},i 0x40,p $hwndparent,t "${verb}",t $\'${app}$\',t $\'${param}$\',t "${workdir}",i ${show})p.r0'
System::Call 'shell32::ShellExecuteEx(t)(pr0)i.r1 ?e' ; (t) to trigger A/W selection
${If} $1 <> 0
${If} $1 <> 0
System::Call '*$0(is,i,i,i,i,i,i,i,i,i,i,i,i,i,ir1)' ;stack value not really used, just a fancy pop ;)
System::Call '*$0(is,i,p,p,p,p,p,p,p,p,p,p,p,p,p.r1)' ;stack value not really used, just a fancy pop ;)
System::Call 'kernel32::WaitForSingleObject(ir1,i-1)'
System::Call 'kernel32::WaitForSingleObject(pr1,i-1)'
System::Call 'kernel32::GetExitCodeProcess(ir1s,*i.r1)'
System::Call 'kernel32::GetExitCodeProcess(pr1,*i.s)'
System::Call 'kernel32::CloseHandle(is)'
System::Call 'kernel32::CloseHandle(pr1)'
${Else}
pop $1
${EndIf}
${EndIf}
System::Free $0
System::Free $0
!if "${exitoutvar}" == ""
pop $0
!endif
System::Store L
!if "${exitoutvar}" != ""
pop ${exitoutvar}
!endif
!macroend
</highlight-nsis>


<highlight-nsis>
!insertmacro ShellExecWait "" '"notepad.exe"' '"c:\config.sys"' "" ${SW_SHOW} $1
MessageBox mb_ok "exitcode or error=$1"
MessageBox mb_ok "exitcode or error=$1"
</highlight-nsis>
</highlight-nsis>

Latest revision as of 15:49, 21 January 2022

Author: Anders (talk, contrib)


Note: NSIS v3.02 added basic support for ExecShellWait.

Basic code for waiting on a "ExecShell" (Note that you can only wait on programs, not documents or URL's)

!include LogicLib.nsh
!include WinMessages.nsh
 
!macro ShellExecWait verb app param workdir show exitoutvar ;only app and show must be != "", every thing else is optional
#define SEE_MASK_NOCLOSEPROCESS 0x40 
System::Store S
!if "${NSIS_PTR_SIZE}" > 4
!define /ReDef /math SYSSIZEOF_SHELLEXECUTEINFO 14 * ${NSIS_PTR_SIZE}
!else ifndef SYSSIZEOF_SHELLEXECUTEINFO
!define SYSSIZEOF_SHELLEXECUTEINFO 60
!endif
System::Call '*(&i${SYSSIZEOF_SHELLEXECUTEINFO})i.r0'
System::Call '*$0(i ${SYSSIZEOF_SHELLEXECUTEINFO},i 0x40,p $hwndparent,t "${verb}",t $\'${app}$\',t $\'${param}$\',t "${workdir}",i ${show})p.r0'
System::Call 'shell32::ShellExecuteEx(t)(pr0)i.r1 ?e' ; (t) to trigger A/W selection
${If} $1 <> 0
	System::Call '*$0(is,i,p,p,p,p,p,p,p,p,p,p,p,p,p.r1)' ;stack value not really used, just a fancy pop ;)
	System::Call 'kernel32::WaitForSingleObject(pr1,i-1)'
	System::Call 'kernel32::GetExitCodeProcess(pr1,*i.s)'
	System::Call 'kernel32::CloseHandle(pr1)'
${EndIf}
System::Free $0
!if "${exitoutvar}" == ""
	pop $0
!endif
System::Store L
!if "${exitoutvar}" != ""
	pop ${exitoutvar}
!endif
!macroend
!insertmacro ShellExecWait "" '"notepad.exe"' '"c:\config.sys"' "" ${SW_SHOW} $1
MessageBox mb_ok "exitcode or error=$1"