Old 9th November 2008, 09:20   #1
Asterix86
Junior Member
 
Join Date: Nov 2008
Location: Paris
Posts: 4
$(^Name) and MUI

Hi,

I try to use the code from [1] to not allow 2 installers to run at the same time. The problem is that it uses $(^Name) to the window name. But I also use MUI, so window name changes according to the current page ("Language Installer", "Installation de XXX", ...)

So my question is: Is it possible to get all those window names from MUI so I can test them all to detect if installer is already running?

Thanks for your help,
Asterix


[1] http://nsis.sourceforge.net/Games_Ex...nce_at_a_time.
Asterix86 is offline   Reply With Quote
Old 9th November 2008, 09:28   #2
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
A much easier solution is to simply define your installer's name yourself as something unique and fixed.

code:
!define myAppName "Asterix86-SomeAppName"


And then replace ${^Name} in the mutex code with ${myAppName}
Animaether is offline   Reply With Quote
Old 9th November 2008, 09:42   #3
Asterix86
Junior Member
 
Join Date: Nov 2008
Location: Paris
Posts: 4
Will it really work? I mean user32::GetWindowText will return ${myAppName} ? I thought it returns window name ...
Asterix86 is offline   Reply With Quote
Old 9th November 2008, 23:30   #4
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Don't use GetWindowText at all. You're just using a string (-any- string) and using windows' APIs to create a mutex. If you try to create a mutex with that same string, windows will return an error.

Thus in its simplest form:
code:

System::Call 'kernel32::CreateMutexA(i 0, i 0, t "hello") i .r1 ?e'
Pop $0
IntCmp $0 0 +2
MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running."

Animaether is offline   Reply With Quote
Old 10th November 2008, 04:52   #5
Asterix86
Junior Member
 
Join Date: Nov 2008
Location: Paris
Posts: 4
ok, this is the first code of the example, but I like the second example that gives focus to the first installer when I run a second one. But for that, I need the window instance. In the example it's done by cycling on all NSIS windows and looking at its name. There is no problem if there is only one installer running, but if there are others you could give focus to the wrong one.
Asterix86 is offline   Reply With Quote
Old 10th November 2008, 07:56   #6
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Well if finding the window (to give it focus) is the main issue, then we can ignore the mutex stuff

You could...
- just hard code the various page titles, and test for each of the titles (lots of work and requires you to make sure each page title still fits any time you change your installer)

- prefix the page titles with a presumably unique string, in the existing script, this code..
code:

StrCmp $2 "$(^Name)" 0 loop


Will then become something like
code:

StrCpy $2 $2 length-of-prefix
StrCmp $2 "your-prefix" 0 loop


Very little work, and this is mostly maintenance-free, as long as you keep your prefix the same.


- let your installer write to the registry that it is running, and under what title (or maybe hwnd, as an integer), it can be found. That way you can just read that out directly.
This is a bit more work than the prefix method, but is somewhat more future-proof; if you don't like your page titles prefixed / or change the prefix in the future, that method will break - while your registry location probably wouldn't change.
This does mean registry i/o where it's not strictly necessary.

Ideally you'd somehow figure out who owns a mutex you're trying to create and which failed - but I don't think there's a way within the mutex object itself..
Animaether is offline   Reply With Quote
Old 10th November 2008, 14:56   #7
Asterix86
Junior Member
 
Join Date: Nov 2008
Location: Paris
Posts: 4
I don't know how to access MUI window name (that was my first question) But I don't like the idea to prefix those names.

registery sounds a better solution, but there are several windows, so I have to change the hwnd when a new one open, and once again I don't know how to access it.

But that sounds too hard to achieve. So I'll stick with my simple solution, to focus the first NSIS installer. Most likely there will be only one.

Thanks a lot for your help though.
Asterix86 is offline   Reply With Quote
Old 11th November 2008, 02:56   #8
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
code:

; findPrefixedWindow
; usage:
; Push "prefix"
; Call findPrefixedWindow
; Pop result
; Result will be empty and Error flag will be set if no window found
Function findPrefixedWindow
; Stack: <prefix>
Exch $0 ; Stack: $0
Push $1 ; Stack: $1 $0
Push $2 ; Stack: $2 $1 $0
Push $3 ; Stack: $3 $2 $1 $0
Push $4 ; Stack: $4 $3 $2 $1 $0
Push $5 ; Stack: $5 $4 $3 $2 $1 $0
Push $R0 ; Stack: $R0 $5 $4 $3 $2 $1 $0

; $0 - prefix
; $1 - prefix length
; $2 - window hwnd
; $3 - window text
; $4 - sub-part of window text
; $5 - callback identifier
; $R0 - callback pointer

StrLen $1 $0

SetPluginUnload alwaysoff
System::Get "(i.r2, i) iss"
Pop $R0
System::Call "user32::EnumWindows(k R0, i) i.s"
_loop:
Pop $5
StrCmp $5 "callback1" 0 _notfound
System::Call "user32::GetWindowText(ir2,t.r3,i${NSIS_MAX_STRLEN})"
StrCpy $4 $3 $1 ""
StrCmp $4 $0 _found _next
_next:
Push 1 # callback's return value
System::Call "$R0"
goto _loop

_found:
StrCpy $0 $3
goto _done

_notfound:
StrCpy $0 ""
SetErrors

_done:
SetPluginUnload manual
System::Free $R0

; Stack: $R0 $5 $4 $3 $2 $1 $0
Pop $R0 ; Stack: $5 $4 $3 $2 $1 $0
Pop $5 ; Stack: $4 $3 $2 $1 $0
Pop $4 ; Stack: $3 $2 $1 $0
Pop $3 ; Stack: $2 $1 $0
Pop $2 ; Stack: $1 $0
Pop $1 ; Stack: $0
Exch $0 ; Stack: <result>
FunctionEnd



Example use:
code:

Function .onInit
StrCpy $R0 "${myPrefix}"
Push $R0
Call findPrefixedWindow
Pop $0
IfErrors _boo _yay

_boo:
MessageBox MB_OK "Could not find any window title beginning with: [$R0]"
goto _end
_yay:
MessageBox MB_OK "Found window title beginning with: [$R0]$\nWindow title: [$0]"
Abort

_end:
FunctionEnd



But you don't want prefixes, so that wouldn't help much.

As for the window handle thingy (hwnd)
code:

$HWNDPARENT

The decimal HWND of the parent window.


Shouldn't change at all - for a single installer.. unless you're launching different installers throughout the installation.. which would be weird.

And there should be only one installer running, given that you wouldn't allow more than 1 installer to run at the same time (what all this code is partly about, no?)
Animaether is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump