Allow only one installer instance: Difference between revisions
Iceman7523 (talk | contribs) mNo edit summary |
|||
Line 41: | Line 41: | ||
<highlight-nsis> | <highlight-nsis> | ||
Function .onInit | Function .onInit | ||
BringToFront | |||
; Check if already running | ; Check if already running | ||
; If so don't open another but bring to front | ; If so don't open another but bring to front |
Revision as of 18:26, 17 August 2007
Author: Vytautas (talk, contrib) |
Description
The best way is to use a kernel mutex. You can call the Win32 API using the System plug-in. Put this code in the .onInit function:
The Script
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutex") ?e' Pop $R0 StrCmp $R0 0 +3 MessageBox MB_OK "The installer is already running." Abort
'myMutex' should be replaced with a unique value (e.g. ProgramSetup.exe).
The advanced way
This code will bring the already running instance to front, instead of opening a new one. Side Note (Jamyn): Strangely, if the user has first minimized the installer, and then tries to launch another copy, the following code will correctly set the first installer as the active window, but won't "pop" it back up from being minimized. Not sure how to do that simply, but that may be useful. Note (Rescator): Try something like System::Call "user32::ShowWindow(i r1,i 9) i." The 9 is the flag #SW_RESTORE see PSDK for more info on ShowWindow()
System::Call "kernel32::CreateMutexA(i 0, i 0, t '$(^Name)') i .r0 ?e" Pop $0 StrCmp $0 0 launch StrLen $0 "$(^Name)" IntOp $0 $0 + 1 loop: FindWindow $1 '#32770' '' 0 $1 IntCmp $1 0 +4 System::Call "user32::GetWindowText(i r1, t .r2, i r0) i." StrCmp $2 "$(^Name)" 0 loop System::Call "user32::SetForegroundWindow(i r1) i." Abort launch:
Even more advanced
This uses the "advanced way" method. Unlike the function above, it will maximize the window if the installer is minimized.
Function .onInit BringToFront ; Check if already running ; If so don't open another but bring to front System::Call "kernel32::CreateMutexA(i 0, i 0, t '$(^Name)') i .r0 ?e" Pop $0 StrCmp $0 0 launch StrLen $0 "$(^Name)" IntOp $0 $0 + 1 loop: FindWindow $1 '#32770' '' 0 $1 IntCmp $1 0 +4 System::Call "user32::GetWindowText(i r1, t .r2, i r0) i." StrCmp $2 "$(^Name)" 0 loop System::Call "user32::ShowWindow(i r1,i 9) i." ; If minimized then maximize System::Call "user32::SetForegroundWindow(i r1) i." ; Bring to front Abort launch: FunctionEnd