ShellExecEx: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
(Executes files with the ShellExecuteEx api. Gets pid, handle or exit code.) |
m (→Function) |
||
Line 48: | Line 48: | ||
Push $1 ;; Strlen / Counter | Push $1 ;; Strlen / Counter | ||
Push $2 ;; Curchar | Push $2 ;; Curchar | ||
StrLen $1 '$0' | StrLen $1 '$0' | ||
IntCmp $1 0 +6 | IntCmp $1 0 +6 | ||
Line 56: | Line 55: | ||
StrCmp "$2" ":" 0 -4 | StrCmp "$2" ":" 0 -4 | ||
IntOp $1 $1 + 1 | IntOp $1 $1 + 1 | ||
StrCpy $0 "$0" $1 0 | StrCpy $0 "$0" $1 0 | ||
Pop $2 | Pop $2 | ||
Pop $1 | Pop $1 |
Revision as of 09:01, 2 December 2011
Author: Lloigor (talk, contrib) |
Description
Executes files via the ShellExecuteEx api, uses three modes: 1. nowait, returns process id, 2. nowait, returns process handle, and 3. wait mode, returns process exit code.
Example
;; Tests if a process, identified by a handle, still exists !define IfProcExistsH "!insertmacro _IfProcExistsH" !macro _IfProcExistsH _ProcHandle_ _GotoIfTrue_ _GotoIfFalse_ Push "$0" ClearErrors System::Call /nounload 'kernel32::WaitForSingleObject(i ${_ProcHandle_}, i 0) i .r0' IntCmp $0 0 +2 SetErrors Pop $0 IfErrors ${_GotoIfTrue_} ${_GotoIfFalse_} !macroend ${ShellExecEx} $0 '' '"$EXEDIR\test.exe"' '' '' '' 2 loop: /* some code here */ ${IfProcExistsH} $0 0 +3 MessageBox MB_OK "The process still exists." Goto loop MessageBox MB_OK "The process doesn't exists anymore!"
Function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Gets the parent folder ;; P1 :out: Folder containing file or dir (parent folder) ;; P2 :in: File/Dir ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; !define PathPath "!insertmacro _PathPath" !macro _PathPath _RetVal_ _Path_ Push "${_Path_}" Call PathPath Pop "${_RetVal_}" !macroend Function PathPath Exch $0 ;; Path Push $1 ;; Strlen / Counter Push $2 ;; Curchar StrLen $1 '$0' IntCmp $1 0 +6 IntOp $1 $1 - 1 StrCpy $2 "$0" 1 $1 StrCmp "$2" '\' +3 StrCmp "$2" ":" 0 -4 IntOp $1 $1 + 1 StrCpy $0 "$0" $1 0 Pop $2 Pop $1 Exch $0 FunctionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Executes files with the ShellExecuteEx api ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; P1 :out: Return value, depends on the mode (P5) ;; P2 :in: Verb. if="" then it opens with default associated app ;; P3 :in: File ;; P4 :in: File parameters ;; P5 :in: Working directory. if="" then its set to the same dir as the file ;; P6 :in: Show flag. if="" then SH_SHOW is used (http://msdn.microsoft.com/en-us/library/bb762153(v=VS.85).aspx) ;; P7 :in: Mode: 1=Nowait, Return Process Id ;; 2=Nowait, Return Process Handle (must close the handle yourself) ;; 3=Wait, Return Exit Code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; !define ShellExecEx "!insertmacro _ShellExecEx" !macro _ShellExecEx _RetVal_ _Verb_ _File_ _Params_ _WorkDir_ _Show_ _Mode_ Push `${_Mode_}` Push `${_Show_}` Push `${_WorkDir_}` Push `${_Params_}` Push `${_File_}` Push `${_Verb_}` Call ShellExecEx Pop ${_RetVal_} !macroend Function ShellExecEx Exch $0 ;; verb Exch Exch $1 ;; File Exch 2 Exch $2 ;; Params Exch 3 Exch $3 ;; WorkDir Exch 4 Exch $4 ;; Show Exch 5 Exch $5 ;; Mode Push "$9" ;; shellexecuteinfo struct StrCmpS "" "$3" 0 wdok ${PathPath} $3 "$1" wdok: StrCmpS "" "$4" 0 +2 ;; if show mode is undefined, then StrCpy $4 0x05 ; = SH_SHOW System::Call /nounload '*(&i60) i .r9' ;; allocate the structure System::Call /nounload '*$9(i 60, i 0x140, i $HWNDPARENT, t r0, t r1, t r2, t r3, i r4) i .r9' ;; assign the values to the struct System::Call /nounload 'Shell32::ShellExecuteEx(i r9) i .r1' ;; execute the file StrCmpS 0 $1 0 +4 ;; if there was errors, then StrCpy $3 0 ; set return value to 0 and set the error flag SetErrors Goto end System::Call /nounload '*$9(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i .r2)' IntCmp $5 2 +4 0 +6 ;; 1:nowait-pid, 2:nowait-handle, 3:wait-exitcode System::Call /nounload 'kernel32::GetProcessId(i r2) i .r4' System::Call /nounload 'kernel32::CloseHandle(i r2)' Goto end ; handle: StrCpy $4 "$2" Goto end ; wait: System::Call /nounload 'kernel32::WaitForSingleObject(i r2, i -1)' System::Call /nounload 'kernel32::GetExitCodeProcess(i r2,*i .r4)' System::Call /nounload 'kernel32::CloseHandle(i r2)' end: System::Free /nounload $9 Pop $9 Pop $5 Pop $0 Pop $1 Pop $2 Pop $3 Exch $4 FunctionEnd