diff --git a/Build/Installer/Installer.nsi b/Build/Installer/Installer.nsi index 0d3260f0..1cf8b00d 100644 --- a/Build/Installer/Installer.nsi +++ b/Build/Installer/Installer.nsi @@ -31,7 +31,6 @@ ReserveFile ".\UAC.dll" !include "MUI2.nsh" !include "x64.nsh" -!include "ProcFunc.nsh" !include "FileFunc.nsh" !include "WordFunc.nsh" !include "WinVer.nsh" @@ -636,27 +635,27 @@ Section SetOutPath "$INSTDIR" - FindWindow $0 "DummyRainWClass" "Rainmeter control window" - ${If} $0 != "0" - SendMessage $0 ${WM_CLOSE} 0 0 + ; Close Rainmeter (and wait up to five seconds) + ${ForEach} $0 10 0 - 1 + FindWindow $1 "DummyRainWClass" "Rainmeter control window" + ${If} $1 == 0 + ${Break} + ${EndIf} - ; Wait up to for up to 5 seconds for Rainmeter to close - StrCpy $1 "0" - ${DoWhile} ${ProcessExists} "Rainmeter.exe" - IntOp $1 $1 + 1 - ${If} $1 >= "10" - ${If} ${Silent} - SetErrorLevel ${ERROR_CLOSEFAIL} - Quit - ${Else} - MessageBox MB_RETRYCANCEL|MB_ICONSTOP "$(RAINMETERCLOSEERROR)" IDRETRY +2 - Quit - ${EndIf} + SendMessage $1 ${WM_CLOSE} 0 0 + + ${If} $0 == 0 + ${If} ${Silent} + SetErrorLevel ${ERROR_CLOSEFAIL} + Quit + ${Else} + MessageBox MB_RETRYCANCEL|MB_ICONSTOP "$(RAINMETERCLOSEERROR)" IDRETRY +2 + Quit ${EndIf} - Sleep 500 - SendMessage $0 ${WM_CLOSE} 0 0 - ${Loop} - ${EndIf} + ${EndIf} + + Sleep 500 + ${Next} ; Check if Rainmeter.ini is located in the installation folder and ; if the installation folder is in Program Files @@ -852,21 +851,27 @@ Function un.GetOptions FunctionEnd Section Uninstall - FindWindow $0 "RainmeterTrayClass" - ${If} $0 != "0" - Exec '"$INSTDIR\Rainmeter.exe" !RainmeterQuit' + ; Close Rainmeter (and wait up to five seconds) + ${ForEach} $0 10 0 - 1 + FindWindow $1 "DummyRainWClass" "Rainmeter control window" + ${If} $1 == 0 + ${Break} + ${EndIf} - ; Wait up to for up to 5 seconds for Rainmeter to close - StrCpy $1 "0" - ${DoWhile} ${ProcessExists} "Rainmeter.exe" - IntOp $1 $1 + 1 - ${If} $1 >= "10" + SendMessage $1 ${WM_CLOSE} 0 0 + + ${If} $0 == 0 + ${If} ${Silent} + SetErrorLevel ${ERROR_CLOSEFAIL} + Quit + ${Else} MessageBox MB_RETRYCANCEL|MB_ICONSTOP "$(RAINMETERCLOSEERROR)" IDRETRY +2 Quit ${EndIf} - Sleep 500 - ${Loop} - ${EndIf} + ${EndIf} + + Sleep 500 + ${Next} RMDir /r "$TEMP\Rainmeter-Cache" RMDir /r "$INSTDIR\Skins\Gnometer" diff --git a/Build/Installer/ProcFunc.nsh b/Build/Installer/ProcFunc.nsh deleted file mode 100644 index 74b0b9d0..00000000 --- a/Build/Installer/ProcFunc.nsh +++ /dev/null @@ -1,835 +0,0 @@ -/* -_____________________________________________________________________________ - - Process Functions Header v2.2 -_____________________________________________________________________________ - - 2008-2010 Erik Pilsits aka wraithdu - License: zlib/libpng - - See documentation for more information about the following functions. - - Usage in script: - 1. !include "ProcFunc.nsh" - 2. [Section|Function] - ${ProcFunction} "Param1" "Param2" "..." $var - [SectionEnd|FunctionEnd] - - - ProcFunction=[GetProcessPID|GetProcessPath|GetProcessParent|GetProcessName| - EnumProcessPaths|ProcessWait|ProcessWait2|ProcessWaitClose| - CloseProcess|TerminateProcess|Execute] - - There is also a LogicLib extension: - ${If} ${ProcessExists} file.exe - ... - ${EndIf} - -_____________________________________________________________________________ - - Thanks to: -_____________________________________________________________________________ - -Some functions based on work by Donald Miller and Phoenix1701@gmail.com - -_____________________________________________________________________________ - - Individual documentation: -_____________________________________________________________________________ - -${ProcessExists} "[process]" - "[process]" ; Name or PID - - Use with a LogicLib conditional command like If or Unless. - Evaluates to true if the process exists or false if it does not or - the CreateToolhelp32Snapshot fails. - -${GetProcessPID} "[process]" $var - "[process]" ; Name or PID - - $var(output) ; -2 - CreateToolhelp32Snapshot failed - ; 0 - process does not exist - ; >0 - PID - -${GetProcessPath} "[process]" $var - "[process]" ; Name or PID - - $var(output) ; -2 - CreateToolhelp32Snapshot failed - ; -1 - OpenProcess failed - ; 0 - process does not exist - ; Or path to process - -${GetProcessParent} "[process]" $var - "[process]" ; Name or PID - - $var(output) ; -2 - CreateToolhelp32Snapshot failed - ; 0 - process does not exist - ; Or PPID - -${GetProcessName} "[PID]" $var - "[PID]" ; PID - - $var(output) ; -2 - CreateToolhelp32Snapshot failed - ; 0 - process does not exist - ; Or process name - -${EnumProcessPaths} "Function" $var - "Function" ; Callback function - $var(output) ; -2 - EnumProcesses failed - ; 1 - success - - Function "Function" - Pop $var1 ; matching path string - Pop $var2 ; matching process PID - ...user commands - Push [1/0] ; must return 1 on the stack to continue - ; must return some value or corrupt the stack - ; DO NOT save data in $0-$9 - FunctionEnd - -${ProcessWait} "[process]" "[timeout]" $var - "[process]" ; Name - "[timeout]" ; -1 - do not timeout - ; >0 - timeout in milliseconds - - $var(output) ; -2 - CreateToolhelp32Snapshot failed - ; -1 - operation timed out - ; Or PID - -${ProcessWait2} "[process]" "[timeout]" $var - "[process]" ; Name - "[timeout]" ; -1 - do not timeout - ; >0 - timeout in milliseconds - - $var(output) ; -1 - operation timed out - ; Or PID - -${ProcessWaitClose} "[process]" "[timeout]" $var - "[process]" ; Name - "[timeout]" ; -1 - do not timeout - ; >0 - timeout in milliseconds - - $var(output) ; -1 - operation timed out - ; 0 - process does not exist - ; Or PID of ended process - -${CloseProcess} "[process]" $var - "[process]" ; Name or PID - - $var(output) ; 0 - process does not exist - ; Or PID of ended process - -${TerminateProcess} "[process]" $var - "[process]" ; Name or PID - - $var(output) ; -1 - operation failed - ; 0 - process does not exist - ; Or PID of ended process - -${Execute} "[command]" "[working_dir]" $var - "[command]" ; '"X:\path\to\prog.exe" arg1 arg2 "arg3 with space"' - "[working_dir]" ; Working directory ("X:\path\to\dir") or nothing ("") - - $var(output) ; 0 - failed to create process - ; Or PID -*/ - - -;_____________________________________________________________________________ -; -; Macros -;_____________________________________________________________________________ -; -; Change log window verbosity (default: 3=no script) -; -; Example: -; !include "ProcFunc.nsh" -; ${PROCFUNC_VERBOSE} 4 # all verbosity -; ${PROCFUNC_VERBOSE} 3 # no script - -!ifndef PROCFUNC_INCLUDED -!define PROCFUNC_INCLUDED - -!include Util.nsh -!include LogicLib.nsh - -!verbose push -!verbose 3 -!ifndef _PROCFUNC_VERBOSE - !define _PROCFUNC_VERBOSE 3 -!endif -!verbose ${_PROCFUNC_VERBOSE} -!define PROCFUNC_VERBOSE `!insertmacro PROCFUNC_VERBOSE` -!verbose pop - -!macro PROCFUNC_VERBOSE _VERBOSE - !verbose push - !verbose 3 - !undef _PROCFUNC_VERBOSE - !define _PROCFUNC_VERBOSE ${_VERBOSE} - !verbose pop -!macroend - -!define PROCESS_QUERY_INFORMATION 0x0400 -!define PROCESS_TERMINATE 0x0001 -!define PROCESS_VM_READ 0x0010 -!define SYNCHRONIZE 0x00100000 - -!define WAIT_TIMEOUT 0x00000102 - -!ifdef NSIS_UNICODE - !define _PROCFUNC_WSTRING "&w260" -!else - !define _PROCFUNC_WSTRING "&w520" -!endif - -!macro ProcessExists - !error "ProcessExists has been renamed to GetProcessPID" -!macroend -!macro _ProcessExists _a _b _t _f - !insertmacro _LOGICLIB_TEMP - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push `${_b}` - ${CallArtificialFunction} LLProcessExists_ - IntCmp $_LOGICLIB_TEMP 0 `${_f}` - Goto `${_t}` - !verbose pop -!macroend -!define ProcessExists `"" ProcessExists` - -!macro GetProcessPID -!macroend -!define GetProcessPID "!insertmacro GetProcessPIDCall" -!macro GetProcessPIDCall process outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push 0 - Push `${process}` - !ifdef CallArtificialFunction_TYPE ; macro nesting disallowed, breaks otherwise if used from WaitClose - ${CallArtificialFunction2} ProcFuncs_ - !else - ${CallArtificialFunction} ProcFuncs_ - !endif - Pop ${outVar} - !verbose pop -!macroend - -!macro GetProcessPath -!macroend -!define GetProcessPath "!insertmacro GetProcessPathCall" -!macro GetProcessPathCall process outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push 1 - Push `${process}` - ${CallArtificialFunction} ProcFuncs_ - Pop ${outVar} - !verbose pop -!macroend - -!macro GetProcessParent -!macroend -!define GetProcessParent "!insertmacro GetProcessParentCall" -!macro GetProcessParentCall process outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push 2 - Push `${process}` - ${CallArtificialFunction} ProcFuncs_ - Pop ${outVar} - !verbose pop -!macroend - -!macro GetProcessName -!macroend -!define GetProcessName "!insertmacro GetProcessNameCall" -!macro GetProcessNameCall process outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push 6 - Push `${process}` - ${CallArtificialFunction} ProcFuncs_ - Pop ${outVar} - !verbose pop -!macroend - -!macro EnumProcessPaths -!macroend -!define EnumProcessPaths "!insertmacro EnumProcessPathsCall" -!macro EnumProcessPathsCall user_func outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push $0 - GetFunctionAddress $0 `${user_func}` - Push `$0` - ${CallArtificialFunction} EnumProcessPaths_ - Exch - Pop $0 - Pop ${outVar} - !verbose pop -!macroend - -!macro ProcessWait -!macroend -!define ProcessWait "!insertmacro ProcessWaitCall" -!macro ProcessWaitCall process timeout outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push `${timeout}` - Push `${process}` - ${CallArtificialFunction} ProcessWait_ - Pop ${outVar} - !verbose pop -!macroend - -!macro ProcessWait2 -!macroend -!define ProcessWait2 "!insertmacro ProcessWait2Call" -!macro ProcessWait2Call process timeout outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push `${timeout}` - Push `${process}` - ${CallArtificialFunction} ProcessWait2_ - Pop ${outVar} - !verbose pop -!macroend - -!macro ProcessWaitClose -!macroend -!define ProcessWaitClose "!insertmacro ProcessWaitCloseCall" -!macro ProcessWaitCloseCall process timeout outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push `${timeout}` - Push `${process}` - ${CallArtificialFunction} ProcessWaitClose_ - Pop ${outVar} - !verbose pop -!macroend - -!macro CloseProcess -!macroend -!define CloseProcess "!insertmacro CloseProcessCall" -!macro CloseProcessCall process outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push `${process}` - ${CallArtificialFunction} CloseProcess_ - Pop ${outVar} - !verbose pop -!macroend - -!macro TerminateProcess -!macroend -!define TerminateProcess "!insertmacro TerminateProcessCall" -!macro TerminateProcessCall process outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push `${process}` - ${CallArtificialFunction} TerminateProcess_ - Pop ${outVar} - !verbose pop -!macroend - -!macro Execute -!macroend -!define Execute "!insertmacro ExecuteCall" -!macro ExecuteCall cmdline wrkdir outVar - !verbose push - !verbose ${_PROCFUNC_VERBOSE} - Push `${wrkdir}` - Push `${cmdline}` - ${CallArtificialFunction} Execute_ - Pop ${outVar} - !verbose pop -!macroend - -!macro ProcFuncs_ - System::Store "s" ; store registers in System's private stack - Pop $0 ; process / PID - Pop $1 ; mode - - Push 0 ; set return value if not found - - ; set mode of operation in $1 - ${Select} $1 ; mode 0 = GetProcessPID, mode 1 = GetProcessPath, mode 2 = GetProcessParent - ${Case} 0 - StrCpy $2 $0 4 -4 - ${If} $2 == ".exe" - ; exists from process name - StrCpy $1 0 - ${Else} - ; exists from pid - StrCpy $1 1 - ${EndIf} - ${Case} 1 - StrCpy $2 $0 4 -4 - ${If} $2 == ".exe" - ; get path from process name - StrCpy $1 2 - ${Else} - ; get path from pid - StrCpy $1 3 - ${EndIf} - ${Case} 2 - StrCpy $2 $0 4 -4 - ${If} $2 == ".exe" - ; get parent from process name - StrCpy $1 4 - ${Else} - ; get parent from pid - StrCpy $1 5 - ${EndIf} - ${EndSelect} - - System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure - ; take system process snapshot in $3 - System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3' - ${Unless} $3 = -1 - System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4' - ${Unless} $4 = 0 - ${Do} - ${Select} $1 - ${Case3} 0 2 4 - ; get process name in $5 - System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)' - ${Case4} 1 3 5 6 - ; get process PID in $5 - System::Call '*$2(i,i,i .r5)' - ${EndSelect} - ; is this process the one we are looking for? - ${If} $5 == $0 ; string test works ok for numeric PIDs as well - ${Select} $1 ; mode 0/1 = GetProcessPID, mode 2/3 = GetProcessPath, mode 4/5 = GetProcessParent, mode 6 = GetProcessName - ${Case2} 0 1 - ; return pid - Pop $5 ; old return value - System::Call '*$2(i,i,i .s)'; process pid to stack - ${Case2} 2 3 - ; return full path - Pop $5 - ; open process - System::Call '*$2(i,i,i .s)'; process pid to stack - System::Call 'kernel32::OpenProcess(i ${PROCESS_QUERY_INFORMATION}|${PROCESS_VM_READ}, i 0, i s)i .r5' ; process handle to $5 - ${Unless} $5 = 0 - ; full path to stack - System::Call 'psapi::GetModuleFileNameExW(i r5, i 0, w .s, i ${NSIS_MAX_STRLEN})' - System::Call 'kernel32::CloseHandle(i r5)' - ${Else} - Push -1 ; OpenProcess failure return value - ${EndUnless} - ${Case2} 4 5 - ; return parent PID - Pop $5 - System::Call '*$2(i,i,i,i,i,i,i .s)'; parent pid to stack - ${Case} 6 - ; return base name - Pop $5 - System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .s)' - ${EndSelect} - ${Break} - ${EndIf} - System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4' - ${LoopUntil} $4 = 0 - System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot - ${EndUnless} - ${Else} - Pop $5 - Push -2 ; function failure return value - ${EndUnless} - System::Free $2 ; free buffer - - System::Store "l" ; restore registers -!macroend - -!macro EnumProcessPaths_ - System::Store "s" ; store registers in System's private stack - Pop $0 ; user_func - - StrCpy $1 1 ; OK to loop - - System::Alloc 1024 - Pop $2 ; process list buffer - ; get an array of all process ids - System::Call 'psapi::EnumProcesses(i r2, i 1024, *i .r3)i .r4' ; $3 = sizeof buffer - ${Unless} $4 = 0 - IntOp $3 $3 / 4 ; Divide by sizeof(DWORD) to get $3 process count - IntOp $3 $3 - 1 ; decrement for 0 base loop - ${For} $4 0 $3 - ${IfThen} $1 != 1 ${|} ${Break} ${|} - ; get a PID from the array - IntOp $5 $4 * 4 ; calculate offset - IntOp $5 $5 + $2 ; add offset to original buffer address - System::Call '*$5(i .r5)' ; get next PID = $5 - ${Unless} $5 = 0 - System::Call 'kernel32::OpenProcess(i ${PROCESS_QUERY_INFORMATION}|${PROCESS_VM_READ}, i 0, i r5)i .r6' - ${Unless} $6 = 0 ; $6 is hProcess - ; get full path - System::Call 'psapi::GetModuleFileNameExW(i r6, i 0, w .r7, i ${NSIS_MAX_STRLEN})i .r8' ; $7 = path - ${Unless} $8 = 0 ; no path - System::Store "s" ; store registers in System's private stack - Push $5 ; PID to stack - Push $7 ; path to stack - Call $0 ; user func must return 1 on the stack to continue looping - System::Store "l" ; restore registers - Pop $1 ; continue? - ${EndUnless} - System::Call 'kernel32::CloseHandle(i r6)' - ${EndUnless} - ${EndUnless} - ${Next} - Push 1 ; return value - ${Else} - Push -2 ; function failure return value - ${EndUnless} - System::Free $2 ; free buffer - - System::Store "l" ; restore registers -!macroend - -!macro ProcessWait_ - System::Store "s" ; store registers in System's private stack - Pop $0 ; process - Pop $1 ; timeout - - StrCpy $6 1 ; initialize loop - StrCpy $7 0 ; initialize timeout counter - - System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure - ${DoWhile} $6 = 1 ; processwait loop - ; take system process snapshot in $3 - System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3' - ${Unless} $3 = -1 - System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4' - ${Unless} $4 = 0 - ${Do} - ; get process name in $5 - System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)' - ${If} $5 == $0 - ; exists, return pid - System::Call '*$2(i,i,i .s)'; process pid to stack ; process pid - StrCpy $6 0 ; end loop - ${Break} - ${EndIf} - System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4' - ${LoopUntil} $4 = 0 - System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot - ${EndUnless} - ${Else} - Push -2 - ${Break} - ${EndUnless} - ; timeout loop - ${If} $6 = 1 - ${If} $1 >= 0 - IntOp $7 $7 + 500 ; increment timeout counter - ${AndIf} $7 >= $1 ; timed out, break loop - Push -1 ; timeout return value - ${Break} ; end loop if timeout - ${EndIf} - Sleep 500 ; pause before looping - ${EndIf} - ${Loop} ; processwaitloop - System::Free $2 ; free buffer - - System::Store "l" ; restore registers -!macroend - -!macro ProcessWait2_ - System::Store "s" ; store registers in System's private stack - System::Store "P0" ; FindProcDLL return value - Pop $0 ; process - Pop $1 ; timeout - - StrCpy $2 0 ; initialize timeout counter - - ${Do} - FindProcDLL::FindProc $0 - ${IfThen} $R0 = 1 ${|} ${Break} ${|} - ${If} $1 >= 0 - IntOp $2 $2 + 250 - ${AndIf} $2 >= $1 - Push -1 ; timeout return value - ${Break} - ${EndIf} - Sleep 250 - ${Loop} - - ${If} $R0 = 1 ; success, get pid - ${GetProcessPID} $0 $0 - Push $0 ; return pid - ${EndIf} - - System::Store "R0" ; restore registers - System::Store "l" -!macroend - -!macro ProcessWaitClose_ - System::Store "s" ; store registers in System's private stack - Pop $0 ; process / PID - Pop $1 ; timeout - - ; passed process name or pid - StrCpy $2 $0 4 -4 - ${If} $2 == ".exe" - ${GetProcessPID} $0 $0 - ${EndIf} - - ; else passed pid directly - - ${Unless} $0 = 0 - System::Call 'kernel32::OpenProcess(i ${SYNCHRONIZE}, i 0, i r0)i .r2' - ${Unless} $2 = 0 ; $2 is hProcess - System::Call 'kernel32::WaitForSingleObject(i r2, i $1)i .r1' - ${If} $1 = ${WAIT_TIMEOUT} - Push -1 ; timed out - ${Else} - Push $0 ; return pid of ended process - ${EndIf} - System::Call 'kernel32::CloseHandle(i r2)' - ${Else} - Push 0 ; failure return value - ${EndUnless} - ${Else} - Push 0 ; failure return value - ${EndUnless} - - System::Store "l" ; restore registers -!macroend - -!macro CloseProcess_ - System::Store "s" ; store registers in System's private stack - Pop $0 ; process / PID - - ; passed process name or pid - StrCpy $1 $0 4 -4 - ${If} $1 == ".exe" - ${GetProcessPID} $0 $0 - ${EndIf} - - ; else passed pid directly - - ${Unless} $0 = 0 ; $0 = target pid - Push $0 ; return pid of process - ; use EnumWindows and a callback - System::Get '(i .r1, i)i sr4' ; $1 = hwnd, $4 = callback#, s (stack) = source for return value - Pop $3 ; $3 = callback address - System::Call 'user32::EnumWindows(k r3, i)i' ; enumerate top-level windows - ${DoWhile} $4 == "callback1" - System::Call 'user32::GetWindowThreadProcessId(i r1, *i .r2)i' ; $2 = pid that created the window - ${If} $2 = $0 ; match to target pid - SendMessage $1 16 0 0 /TIMEOUT=1 ; send WM_CLOSE to all top-level windows owned by process, timeout immediately - ${EndIf} - Push 1 ; callback return value; keep enumerating windows (returning 0 stops) - StrCpy $4 "" ; clear callback# - System::Call '$3' ; return from callback - ${Loop} - System::Free $3 ; free callback - ${Else} - Push 0 ; failure return value - ${EndUnless} - - System::Store "l" ; restore registers -!macroend - -!macro TerminateProcess_ - System::Store "s" ; store registers in System's private stack - Pop $0 ; process / PID - - ; passed process name or pid - StrCpy $1 $0 4 -4 - ${If} $1 == ".exe" - ${GetProcessPID} $0 $0 - ${EndIf} - - ; else passed pid directly - - ${Unless} $0 = 0 - System::Call 'kernel32::OpenProcess(i ${PROCESS_TERMINATE}, i 0, i r0)i .r1' - ${Unless} $1 = 0 ; $1 is hProcess - System::Call 'kernel32::TerminateProcess(i r1, i 0)i .r1' - ${If} $1 = 0 ; fail - Push -1 - ${Else} - Push $0 ; return pid of ended process - ${EndIf} - System::Call 'kernel32::CloseHandle(i r1)' - ${Else} - Push 0 ; failure return value - ${EndUnless} - ${Else} - Push 0 ; failure return value - ${EndUnless} - - System::Store "l" ; restore registers -!macroend - -!macro Execute_ - System::Store "s" ; store registers in System's private stack - Pop $0 ; cmdline - Pop $1 ; wrkdir - - System::Alloc 68 ; 4*16 + 2*2 / STARTUPINFO structure = $2 - Pop $2 - System::Call '*$2(i 68)' ; set cb = sizeof(STARTUPINFO) - System::Call '*(i,i,i,i)i .r3' ; PROCESS_INFORMATION structure = $3 - - ${If} $1 == "" - StrCpy $1 "i" - ${Else} - StrCpy $1 'w "$1"' - ${EndIf} - - System::Call `kernel32::CreateProcessW(i, w '$0', i, i, i 0, i 0, i, $1, i r2, i r3)i .r4` ; return 0 if fail - ${Unless} $4 = 0 ; failed to create process - System::Call '*$3(i .r4, i .r5, i .r6)' ; read handles and PID - System::Call 'kernel32::CloseHandle(i $4)' ; close hProcess - System::Call 'kernel32::CloseHandle(i $5)' ; close hThread - Push $6 ; return PID - ${Else} - Push 0 ; return val if failed - ${EndUnless} - - System::Free $2 ; free STARTUPINFO struct - System::Free $3 ; free PROCESS_INFORMATION struct - - System::Store "l" ; restore registers -!macroend - -!macro LLProcessExists_ - System::Store "s" ; store registers in System's private stack - Pop $0 ; process name - - StrCpy $_LOGICLIB_TEMP 0 - - System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure - ; take system process snapshot in $3 - System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3' - IntCmp $3 -1 done - System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4' - IntCmp $4 0 endloop - loop: - System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)' - StrCmp $5 $0 0 next_process - StrCpy $_LOGICLIB_TEMP 1 - Goto endloop - next_process: - System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4' - IntCmp $4 0 endloop - Goto loop - endloop: - System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot - done: - System::Free $2 ; free buffer - - System::Store "l" ; restore registers -!macroend - -!endif ; PROCFUNC_INCLUDED - -/**************************************************************************** - Functions - ========= - - HANDLE WINAPI OpenProcess( - __in DWORD dwDesiredAccess, - __in BOOL bInheritHandle, - __in DWORD dwProcessId - ); - - BOOL WINAPI CreateProcess( - __in_opt LPCTSTR lpApplicationName, - __inout_opt LPTSTR lpCommandLine, - __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, - __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, - __in BOOL bInheritHandles, - __in DWORD dwCreationFlags, - __in_opt LPVOID lpEnvironment, - __in_opt LPCTSTR lpCurrentDirectory, - __in LPSTARTUPINFO lpStartupInfo, - __out LPPROCESS_INFORMATION lpProcessInformation - ); - - typedef struct _STARTUPINFO { - DWORD cb; - LPTSTR lpReserved; - LPTSTR lpDesktop; - LPTSTR lpTitle; - DWORD dwX; - DWORD dwY; - DWORD dwXSize; - DWORD dwYSize; - DWORD dwXCountChars; - DWORD dwYCountChars; - DWORD dwFillAttribute; - DWORD dwFlags; - WORD wShowWindow; - WORD cbReserved2; - LPBYTE lpReserved2; - HANDLE hStdInput; - HANDLE hStdOutput; - HANDLE hStdError; - } STARTUPINFO, - *LPSTARTUPINFO; - - typedef struct _PROCESS_INFORMATION { - HANDLE hProcess; - HANDLE hThread; - DWORD dwProcessId; - DWORD dwThreadId; - } PROCESS_INFORMATION, - *LPPROCESS_INFORMATION; - - BOOL WINAPI EnumProcesses( - __out DWORD* pProcessIds, - __in DWORD cb, - __out DWORD* pBytesReturned - ); - - DWORD WINAPI GetModuleBaseName( - __in HANDLE hProcess, - __in_opt HMODULE hModule, - __out LPTSTR lpBaseName, - __in DWORD nSize - ); - - DWORD WINAPI GetModuleFileNameEx( - __in HANDLE hProcess, - __in_opt HMODULE hModule, - __out LPTSTR lpFilename, - __in DWORD nSize - ); - - BOOL WINAPI CloseHandle( - __in HANDLE hObject - ); - - DWORD WINAPI WaitForSingleObject( - __in HANDLE hHandle, - __in DWORD dwMilliseconds - ); - - BOOL WINAPI TerminateProcess( - __in HANDLE hProcess, - __in UINT uExitCode - ); - - BOOL EnumWindows( - __in WNDENUMPROC lpEnumFunc, - __in LPARAM lParam - ); - - DWORD GetWindowThreadProcessId( - __in HWND hWnd, - __out LPDWORD lpdwProcessId - ); - - BOOL PostMessage( - __in HWND hWnd, - __in UINT Msg, - __in WPARAM wParam, - __in LPARAM lParam - ); - -****************************************************************************/ \ No newline at end of file