Allow only one installer instance: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(Note about minimized initial installer)
Line 18: Line 18:
== The advanced way ==
== The advanced way ==
This code will bring the already running instance to front, instead of opening a new one.
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.
<highlight-nsis>
<highlight-nsis>
  System::Call "kernel32::CreateMutexA(i 0, i 0, t '$(^Name)') i .r0 ?e"
  System::Call "kernel32::CreateMutexA(i 0, i 0, t '$(^Name)') i .r0 ?e"

Revision as of 16:19, 10 March 2006

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") i .r1 ?e'
 
  Pop $R0 
 
  StrCmp $R0 0 +3 
    MessageBox MB_OK "The installer is already running." 
    Abort

'myMutex' should be replaced with a unique value.

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.

 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: